本文共 4505 字,大约阅读时间需要 15 分钟。
由于后端项目之间使用rpc进行通讯,没有mvc层。对接前端需要提供http接口给到前端,因此需要有个motan网关来完成对接前端的任务。
翻阅了下资料
https://github.com/weibocom/motan/issues/581 实现motan网关有两种方式1.使用motan-go开发网关。
2.修改motan源码,进行自定义转发。
由于对go语言不熟,修改motan源码的工作量比较大。因此这里选择了一个比较折中的方式。使用springboot开发motan网关,在原有的motan的基础上包装一层转发逻辑,实现motan接口的动态转发。
基本思路如下网关和服务间使用一个公共的motan接口的方法进行调用,然后由公共run方法去根据约定好的规矩进行转发,去调用实际的方法。
这个样做的好处就是我不用关心服务提供方的接口变动情况,只需要按照约定的给定参数就是可以直接调用。无需像普通的motan rpc服务调用需要频繁重启服务。规定服务方听的公共方法为
String run(String param) throws Exception; 参数为String 返回值为String 方法名为run,
调用参数为json字符串,必须包含两个参数 redirectMethod 需要调用的方法,redirectClazz 调用方法的类
这两个主要用来动态调用的时候反射调用到具体方法
有了上面的思路,下面我们来实现下具体的代码。
这个类是核心,里面规定了参数调用,请求方调用方法,和相应方调用方法
package com.happotech.motan.core.util;import com.alibaba.fastjson.JSONObject;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Component;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/** * motan 网关转发util * @author songxulin * @date 2021/4/14 */@Componentpublic class MotanRedirectUtil implements ApplicationContextAware { //spring上下文 private static ApplicationContext applicationContext; public static Object getMotanBean(Class clazz){ return applicationContext.getBean(clazz); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } //发送请求 public static JSONObject requestRun(Object iActMotanService,String param,String ApiUrlPrefix,String redirectMethod) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { param = getParam(param,ApiUrlPrefix,redirectMethod); Method run = iActMotanService.getClass().getMethod("run", String.class); return JSONObject.parseObject(run.invoke(iActMotanService,param).toString()); } //相应请求 public static String responseRun(String param,Class clazz) throws Exception { JSONObject parseObject = JSONObject.parseObject(param); String redirectMethod = parseObject.getString("redirectMethod"); String redirectClazz = parseObject.getString("redirectClazz"); if(clazz.getName().equals(redirectClazz)&&"run".equals(redirectMethod)){ throw new Exception("run 方法不允许重定向"); } Class aClass = Class.forName(redirectClazz); Object motanBean = MotanRedirectUtil.getMotanBean(aClass); Method method = aClass.getMethod(redirectMethod, String.class); Object invoke = method.invoke(motanBean, param); if(invoke instanceof String){ return (String) invoke; } return JSONObject.toJSONString(invoke); } //获取参数 public static String getParam(String body,String ApiUrlPrefix,String redirectMethod){ JSONObject param = JSONObject.parseObject(body); param.put("redirectMethod",redirectMethod); param.put("redirectClazz",ApiUrlPrefix.replaceAll("/",".").substring(1,ApiUrlPrefix.length()-1)); return param.toJSONString(); }}
上面就是核心代码
将核心代码打包,提交到私服和本地仓库中,就可以方便的在网关端和服务端使用了。com.happotech happo-motan-client-core 1.0.1
使用的时,可以将核心代码打包成jar,引入到服务端和网关端使用。
必须包含 String run(String param) 方法。
/** * @author songxulin * @date 2021/4/14 */public interface IActMotanService { String run(String param) throws Exception;}
实现
@MotanServicepublic class ActMotanServiceImpl implements IActMotanService { @Override public String run(String param) throws Exception { return MotanRedirectUtil.responseRun(param,IActMotanService.class); }}
@RestControllerpublic class MotanController { @MotanReferer private IMotanService iMotanService; //ApiUrlPrefix 为接口类的全路径 private static final String ApiUrlPrefix = "/com/happotech/actmgr/motan/service/api/IMgrService/"; @RequestMapping(ApiUrlPrefix + "{method}") @ResponseBody public JSONObject urcService(@RequestBody String body, @PathVariable("method") String method, HttpServletRequest request) throws Exception { return MotanRedirectUtil.requestRun(iActMotanService, body, ApiUrlPrefix, method); }}
这样motan的网关就实现了,后面如果有新的项目加入进来,只需要加入新的的controller就可以了。
motan网关
转载地址:http://gzmlf.baihongyu.com/