Java RPC 框架 Solon 1.3.7 釋出,增強Cloud介面能力範圍

劉之西東發表於2021-03-01

Solon 是一個微型的Java RPC開發框架。專案從2018年啟動以來,參考過大量前人作品;歷時兩年,4000多次的commit;核心保持0.1m的身材,超高的跑分,良好的使用體驗。支援:RPC、REST API、MVC 等多種開發模式。

Solon 強調:剋制 + 簡潔 + 開放的原則;力求:更小、更快、更自由的體驗。

專案地址:

https://gitee.com/noear/solon

所謂更小:

核心0.1m,最小開發單位0.2m(相比Dubbo、Springboot專案包,小到可以乎略不計)

所謂更快:

本機helloworld測試,Qps可達12萬之多。可參考:《helloworld_wrk_test

所謂更自由:(程式碼操控自由)

// 除了註解模式之外,還可以按需手動
//
//手動獲取配置(Props 為 Properties 增強版)
Props db = Solon.cfg().getProp("db");

//手動獲取容器裡的Bean
UserService userService = Aop.get(UserService.class);

//手動監聽http post請求
Solon.global().post("/user/update", x-> userService.updateById(x.paramMap()));

//手動新增個RPC服務
Solon.global().add("/rpc/", HelloService.class, true);

//手動獲取一個RPC服務消費端
HelloService helloService = Nami.builder().create(HelloService.class);

本次版本重大變更:

1、增加 Solon cloud 自定義訊號註冊支援

(一)基於本地的訊號註冊管理

可直接在 SolonApp 例項上,新增訊號源;即完成自動註冊。內部會使用本地IP及訊號資訊向 CloudClient 的發現介面註冊。

  • 例:新增http服務註冊訊號
app.signalAdd(new SignalSim("demoapi", 8080, "http", SignalType.HTTP));
  • 例:新增tcp服務註冊訊號
app.signalAdd(new SignalSim("demorpc", 28080, "tcp", SignalType.SOCKET));
  • 例:新增websocket服務註冊訊號
app.signalAdd(new SignalSim("demows", 18080, "ws", SignalType.WEBSOCKET));
  • 例:新增dubbo服務註冊訊號
app.signalAdd(new SignalSim("demodubbo", 20880, "dubbo", SignalType.SOCKET));

(二)基於網路的訊號註冊管理

通過 CloudClient 的發現介面註冊例項的方式實現。此方式,可新增更豐富的資訊,如meta、tag...

Instance n1 = new Instance("demoapi", "127.0.0.1:1212");
n1.protocol("tcp");
n1.metaPut("athor","noear");
n1.tagAdd("solon");

CloudClient.discovery().register("demo", n1);

2、增加安全停止功能

內部原理:1) 執行外掛的預停止方法;2) 等待10秒;3) 執行外掛的停止方法。以Solon cloud 外掛為例,預停止時會通過發現介面登出當前服務,從而有10秒的時間讓發現系統通知各消費端。

從而讓基於發現服務的專案,達到無感知更新的效果。

  • 啟用安全停目能力
//通過 enableSafeStop 特性,開啟安全停止能力
Solon.start(TestApp.class, args, app -> app.enableSafeStop(true));
  • 配置等待或延時秒數
solon.stop.delay=10

3、增加分散式鎖介面: CloudLockService

引入適配外掛之後,使用示例:

//1.嘗試鎖
if (CloudClient.lock().lock(Solon.cfg().appName(), "order_" + 12, 3)) {
    try {
        //2.1.業務操作
    } finally {
        //3.處理完後,解鎖
        CloudClient.lock().unlock(Solon.cfg().appName(), "order_" + 12);
    }
}else{
    //2.2
    //提示處理
}

4、增加日誌介面元件,對接: CloudLogService

增加基於Slf4j介面的 solon.logging 和 solon.logging.impl 日誌元件,為雲端日誌服務提供統一介面;同時也方便使用者切換為第三方日誌服務元件。(目前water-solon-plugin 已適配 CloudLogService,從而提供雲端記錄和查詢服務)

  • 特性:增強的 TagsMDC ,有利於日誌的元資訊固化儲存,以及後期的查詢
@Slf4j
public class LogDemo{
    public void test(){
        // 記錄當前請求的輸入輸出日誌,並帶上使用者ID與訂單ID作為查詢標籤
        //
        TagsMDC.tag0("order_"+12);
        TagsMDC.tag1("user_"+1);
        
        Context ctx = Context.current();
        log.info("::{}\r\n{}", ctx.paramMap(), ctx.result);
    }
}

  • 日誌控制檯輸出示例
[INFO] 2021-02-24T22:29:11.822 [*main][@tag0:order_12][@tag3:user_1] demo.LogDemo#console:
::{user:1, order:12}
::{code:1, description:"", data:{list:[...]}}
  • 自定義日誌新增器示例

編寫程式碼

public class TestAppender extends LogAbstractAppender {
    @Override
    public String getName() {
        return "test";
    }

    @Override
    protected void appendDo(LogEvent logEvent) {
        //可以存為本地檔案;
        //可以存到訊息佇列;
        //可以存到MongoDB;
        //可以存到HBase;
        //可以存到 RDB.....等
        System.out.println("[Test] " + logEvent.getContent());
    }
}

//
// 或者適配 CloudLogService 介面,成為 Solon cloud 家族的一員
//

配置使用

solon.logging.appender:
  test: #新增器名字,與getName() 對應起來
    class: webapp.demox_mlog.TestAppender #新增器的實現類
    level: TRACE #新增器接收的日誌級別(TRACE、DEBUG、INFO、WARN、ERROR)
    enable: true #預設為開啟

在中小流量專案,可存於RDB(相對於HBase和ES,會便宜很多),寫入時建議用記憶體佇列中轉再批量寫入RDB。結構可參考:

CREATE TABLE `demoapi_log` (
 `log_id` bigint NOT NULL,
  `trace_id` varchar(40) DEFAULT NULL COMMENT '鏈路跟蹤ID',
  `level` int NOT NULL DEFAULT '0',
  `tag0` varchar(100) NOT NULL COMMENT '標籤',
  `tag1` varchar(100) NOT NULL DEFAULT '',
  `tag2` varchar(100) NOT NULL DEFAULT '',
  `tag3` varchar(100) NOT NULL DEFAULT '',
  `content` longtext COMMENT '內容',
  `from` varchar(200) DEFAULT NULL COMMENT '日誌來源',
  `log_date` int NOT NULL DEFAULT '0' COMMENT '記錄日期',
  `log_timestamp` bigint NOT NULL COMMENT '記錄時間戳',
  PRIMARY KEY (`log_id`) USING BTREE,
  KEY `IX_tag0` (`tag0`) USING BTREE,
  KEY `IX_tag1` (`tag1`) USING BTREE,
  KEY `IX_tag2` (`tag2`) USING BTREE,
  KEY `IX_tag3` (`tag3`) USING BTREE,
  KEY `IX_trace_id` (`trace_id`) USING BTREE,
  KEY `IX_date` (`log_date`) USING BTREE,
  KEY `log_timestamp` (`log_timestamp`) USING BTREE,
  KEY `IX_level` (`level`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

實現,可參考 water-solon-plugin 的 CloudLogServiceImp

  • 日誌新增器情況

引入 solon.logging.impl ,預設新增內建的:LogConsoleAppender (預設級別:TRACE)

引入 solon.cloud ,預設再新增:CloudLogAppender (預設級別:INFO,且將資料轉發到 CloudLogService )

可通過如下配置進行級別控制和啟動狀態:

solon.logging.appender:
  console: 
    level: TRACE
    enable: true
  cloud:
    level: INFO
    enable: true

附:入門示例

相關文章