实测Tengine开源的Dubbo功能

本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star。

背景

  • Tengine是阿里巴巴基于Nginx开发并开源的Web服务器,它继承了Nginx所有的功能和特性,并在其基础上做了大量的扩展和增强,其中像动态模块加载,四层负载均衡,reuseport支持等能力,都逐渐被Nginx官方吸收引用。Tengine在开源以后大受欢迎,成为了Nginx最好的替代品之一,官方网站(http://tengine.taobao.org/)。

  • Dubbo是阿里巴巴开源的一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

2019年9月,Tengine 2.3.2版本发布了dubbo_pass模块,支持HTTP协议到Dubbo协议的转换。Release页面如下:

https://github.com/alibaba/tengine/releases/tag/2.3.2

意义

《Gateway技术革命 - Tengine开源Dubbo功能》对Tengine支持Dubbo协议的意义讲的比较清楚,总结有如下几点:

  • 架构优化:减少一层转发,降低系统复杂度;
  • 性能优势:文中给出数据,“Tengine直接支持Dubbo的架构在CPU消耗和RT上的表现在不同场景下,有28%-73%不等的性能优势”

实测

Tengine环境搭建

这里我用centos的基础镜像搭了一套Tengine环境,简单说明一下步骤:

  • 进入容器,创建工作目录
mkdir -p /home/roshi && cd /home/roshi/
  • 下载相关源码并解压
1wget https://github.com/alibaba/tengine/archive/2.3.2.zip 2unzip 2.3.2.zip && cd tengine-2.3.2/ 3 4wget https://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz 5tar xvf pcre-8.43.tar.gz 6 7wget https://www.openssl.org/source/openssl-1.0.2s.tar.gz 8tar xvf openssl-1.0.2s.tar.gz 9 10wget http://www.zlib.net/zlib-1.2.11.tar.gz 11tar xvf zlib-1.2.11.tar.gz
  • 安装相关依赖
1yum install gcc 2yum install gcc-c++ 3yum -y install gcc automake autoconf libtool make
  • 编译
1./configure --add-module=./modules/mod_dubbo --add-module=./modules/ngx_multi_upstream_module --add-module=./modules/mod_config --with-pcre=./pcre-8.43/ --with-openssl=./openssl-1.0.2s/ --with-zlib=./zlib-1.2.11 2make && make install
  • 启动
/usr/local/nginx/sbin/nginx

Dubbo例子

这里要提一下之前在《dubbo应用级服务发现初体验》中提到的快速搭建Dubbo调试环境的方法:

由于Tengine有限制,接口的出参和入参必须是Map<String, Object>,所以需要对例子进行修改:

  • DemoService
1public interface DemoService { 2 3 String sayHello(String name); 4 5 default Map<String, Object> testTengine(Map<String, Object> args) { 6 return null; 7 } 8 9 default CompletableFuture<String> sayHelloAsync(String name) { 10 return CompletableFuture.completedFuture(sayHello(name)); 11 } 12}
  • DemoServiceImpl.java
1public class DemoServiceImpl implements DemoService { 2 private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class); 3 4 @Override 5 public String sayHello(String name) { 6 logger.info("Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress()); 7 return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress(); 8 } 9 10 @Override 11 public Map<String, Object> testTengine(Map<String, Object> args) { 12 Map<String, Object> res = new HashMap<>(); 13 res.put("body", "hello tengine dubbo\n"); 14 res.put("status", "200"); 15 System.out.println("testTengine"); 16 return res; 17 } 18 19 @Override 20 public CompletableFuture<String> sayHelloAsync(String name) { 21 return null; 22 } 23 24}

为了更好的测试多个provider的情况,可以用同一份代码,在不同的端口起多个服务。

修改Tengine配置

  • vi /usr/local/nginx/conf/nginx.conf
1worker_processes 1; 2 3events { 4 worker_connections 1024; 5} 6 7http { 8 include mime.types; 9 default_type application/octet-stream; 10 11 sendfile on; 12 13 server { 14 listen 8080; 15 server_name localhost; 16 17 #pass the Dubbo to Dubbo Provider server listening on 127.0.0.1:20880 18 location / { 19 dubbo_pass_all_headers on; 20 # dubbo_pass_set args $args; 21 dubbo_pass_set args hello; 22 dubbo_pass_set uri $uri; 23 dubbo_pass_set method $request_method; 24 25 dubbo_pass org.apache.dubbo.demo.DemoService 0.0.0 testTengine dubbo_backend; 26 } 27 } 28 29 30 #pass the Dubbo to Dubbo Provider server listening on 127.0.0.1:20880 31 upstream dubbo_backend { 32 multi 1; 33 server host.docker.internal:20880; 34 server host.docker.internal:20881; 35 } 36}
  • 修改配置后reload配置,使其生效
/usr/local/nginx/sbin/nginx -s reload

测试

使用如下命令测试

curl -X POST http://127.0.0.1:8080/dubbo -i -d "hello=roshi"

看一下传参情况

总结

经过测试,总结以下几点:

  • 接口的出参入参固定为Map<String, Object>,否则会报错
  • 使用body传参,到Dubbo侧是byte[],还需要解析
  • 可以控制返回的body和http状态码,其中返回的body可以是String,也可以是byte[]类型,状态码是String类型
  • 具备Tengine原生的负载均衡算法
  • 具备故障摘除,Tegine与Dubbo Provider会建立长连接,断开则摘除
  • 未实现version、group分组功能,文档中的version实测没有任何效果

最后

正如《Gateway技术革命 - Tengine开源Dubbo功能》文中所说,Tengine只是完成了作为Dubbo Consumer的协议支持,像服务发现、自定义接口、服务分组、容错降级等其他功能暂未实现,暂时还离生产有些距离。

最后吐槽一下Tengine官网的文档

参考


搜索关注微信公众号"捉虫大师",后端技术分享,架构设计、性能优化、源码阅读、问题排查、踩坑实践。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )