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