APISIX dubbo-proxy 实战
APISIX
APISIX 声称支持 Dubbo Proxy
实践
主要是 APISIX 官方网站上的这篇博客写的问题很大。
博客上写的 HTTP2DubboService 实现类
@Component
public class HTTP2DubboServiceImpl implements HTTP2DubboService {
@Autowired
private ApplicationContext appContext;
@Override
public Map<String, Object> invoke(Map<String, Object> context) throws Exception {
DubboInvocation invocation = JSONObject.parseObject((byte[]) context.get("body"), DubboInvocation.class);
Object[] args = new Object[invocation.getParameters().size()];
for (int i = 0; i < args.length; i++) {
DubboInvocationParameter parameter = invocation.getParameters().get(i);
args[i] = JSONObject.parseObject(parameter.getValue(), Class.forName(parameter.getType()));
}
Object svc = appContext.getBean(Class.forName(invocation.getService()));
Object result = svc.getClass().getMethod(invocation.getMethod()).invoke(args);
Map<String, Object> httpResponse = new HashMap<>();
httpResponse.put("status", 200);
httpResponse.put("body", JSONObject.toJSONString(result));
return httpResponse;
}
}
槽点1
首先名字就很让人误解:HTTP2Dubbo,其实这个根本不是HTTP协议。这个是 Tengine 提供的 mod_dubbo 实现的功能,openresty/tengine 接收的是 HTTP数据报文,但是对于应用程序提供者,仍然不是HTTP协议。
本质上,要让 APISIX 的 Dubbo Proxy 能调用成功,还是有很多前提条件的。
槽点2
官方给的 Demo 没问题,但是没有强调这点:入参和出参只支持 Map<String, Object> ,否则500 Bad Gateway。
槽点3
上述程序,作用是将统一的参数转换成反射调用,调用实际方法,但是这能跑的通?
-
如果参数类型为 com.slankka.service.dubbo.ISampleService.getData(java.lang.Long, java.lang.String)。
这样会导致 JSONObject.parseObject("string value", String.class), 这样无论是 fastjson,fastjson2还是 jackson 都是会失败的。 -
反射是这样用的吗?
svc.getClass().getMethod(invocation.getMethod()).invoke(args);
实际上应该是这样用的
Class<?>[] = ...
parameterTypes[i] = Class.forName(parameter.getType())
svc.getClass().getMethod(invocation.getMethod(), parameterTypes).invoke(svc, args);
槽点4
apisix的 nginx 返回值,Content-Type 是 text/plain; 这样岂不是要了 OpenFeign 的命!Spring Cloud OpenFeign,RestTemplate, Spring HttpMessageConverter 全部反对!
HTTP/1.1 200 OK
Date: Sun, 24 Dec 2023 12:16:29 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 178
Connection: keep-alive
Server: APISIX/3.2.1
实际情况可能因apisix自己编译 mod_dubbo 的实现有关
解决办法是 设置HTTP Response Header
Map<String, Object> httpResponse = new HashMap<>();
httpResponse.put("status", 200);
httpResponse.put("Content-Type", "application/json; charset=utf-8");
httpResponse.put("body", JSONObject.toJSONString(result));
槽点5
Dubbo-proxy 插件的 service_version 不支持 1.0
,只支持\d+.\d+.\d+
如果是 1.0
则报错:
failed to check the configuration of plugin dubbo-proxy err: property "service_version" validation failed: failed to match pattern "^\\d+\\.\\d+\\.\\d+" with "1.0"
参考文档
Tengine: Dubbo Example
APISIX dubbo-proxy
实测Tengine开源的Dubbo功能
通过网关将 http 流量接入 Dubbo 后端服务
让你在 Apache APISIX 中代理 Dubbo 服务更便捷
Tengine Header Response Content-Type
github.com/api7/mod_dubbo
github.com/api7/apisix-build-tools
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2021-12-24 Invalid bound statement (not found) @Update注解写的怎么还报错!