實測Tengine開源的Dubbo功能

捉蟲大師發表於2022-02-24

本文已收錄 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/
  • 下載相關原始碼並解壓
wget https://github.com/alibaba/tengine/archive/2.3.2.zip
unzip 2.3.2.zip && cd tengine-2.3.2/

wget https://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz
tar xvf pcre-8.43.tar.gz

wget https://www.openssl.org/source/openssl-1.0.2s.tar.gz
tar xvf openssl-1.0.2s.tar.gz

wget http://www.zlib.net/zlib-1.2.11.tar.gz
tar xvf zlib-1.2.11.tar.gz
  • 安裝相關依賴
yum install gcc
yum install gcc-c++
yum -y install gcc automake autoconf libtool make
  • 編譯
./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
make && make install
  • 啟動
/usr/local/nginx/sbin/nginx

Dubbo例子

這裡要提一下之前在《dubbo應用級服務發現初體驗》中提到的快速搭建Dubbo除錯環境的方法:

由於Tengine有限制,介面的出參和入參必須是Map<String, Object>,所以需要對例子進行修改:

  • DemoService
public interface DemoService {

    String sayHello(String name);

    default Map<String, Object> testTengine(Map<String, Object> args) {
        return null;
    }

    default CompletableFuture<String> sayHelloAsync(String name) {
        return CompletableFuture.completedFuture(sayHello(name));
    }
}
  • DemoServiceImpl.java
public class DemoServiceImpl implements DemoService {
    private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class);

    @Override
    public String sayHello(String name) {
        logger.info("Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
        return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress();
    }

    @Override
    public Map<String, Object> testTengine(Map<String, Object> args) {
        Map<String, Object> res = new HashMap<>();
        res.put("body", "hello tengine dubbo\n");
        res.put("status", "200");
        System.out.println("testTengine");
        return res;
    }

    @Override
    public CompletableFuture<String> sayHelloAsync(String name) {
        return null;
    }

}

為了更好的測試多個provider的情況,可以用同一份程式碼,在不同的埠起多個服務。

修改Tengine配置

  • vi /usr/local/nginx/conf/nginx.conf
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    server {
        listen       8080;
        server_name  localhost;

        #pass the Dubbo to Dubbo Provider server listening on 127.0.0.1:20880
        location / {
            dubbo_pass_all_headers on;
            # dubbo_pass_set args $args;
            dubbo_pass_set args hello;
            dubbo_pass_set uri $uri;
            dubbo_pass_set method $request_method;

            dubbo_pass org.apache.dubbo.demo.DemoService 0.0.0 testTengine dubbo_backend;
        }
    }


    #pass the Dubbo to Dubbo Provider server listening on 127.0.0.1:20880
    upstream dubbo_backend {
        multi 1;
        server host.docker.internal:20880;
        server host.docker.internal:20881;
    }
}
  • 修改配置後reload配置,使其生效
/usr/local/nginx/sbin/nginx -s reload

測試

使用如下命令測試

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

image

看一下傳參情況

image

總結

經過測試,總結以下幾點:

  • 介面的出參入參固定為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官網的文件

image

參考


搜尋關注微信公眾號"捉蟲大師",後端技術分享,架構設計、效能優化、原始碼閱讀、問題排查、踩坑實踐。

相關文章