Java RPC framework Solon 1.3.7 released, enhancing the scope of Cloud interface capabilities

Solon is a tiny Java RPC development framework. Since the project was launched in 2018, a large number of previous works have been referenced; it took two years and more than 4,000 commits; the kernel maintains a figure of 0.1m, super high running score, and good user experience. Support: RPC, REST API, MVC and other development modes.

Solon emphasizes the principle of restraint + simplicity + openness; strives for a smaller, faster and more free experience.

The so-called smaller:

The kernel is 0.1m, and the smallest development unit is 0.2m (compared to Dubbo and Springboot project packages, so small that it can be neglected)

The so-called faster:

The local helloworld test, Qps can reach as much as 120,000. Can refer to: " helloworld_wrk_test "

The so-called more freedom: (free code manipulation)

// 除了注解模式之外,还可以按需手动
//
//手动获取配置(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);

Major changes in this version:

1. Add Solon cloud custom signal registration support

(1) Local-based signal registration management

You can directly add a signal source on the SolonApp instance; that is, automatic registration is completed. The local IP and signal information will be used internally to register with the discovery interface of CloudClient.

  • Example: add http service registration signal
app.signalAdd(new SignalSim("demoapi", 8080, "http", SignalType.HTTP));
  • Example: add tcp service registration signal
app.signalAdd(new SignalSim("demorpc", 28080, "tcp", SignalType.SOCKET));
  • Example: add websocket service registration signal
app.signalAdd(new SignalSim("demows", 18080, "ws", SignalType.WEBSOCKET));
  • Example: add dubbo service registration signal
app.signalAdd(new SignalSim("demodubbo", 20880, "dubbo", SignalType.SOCKET));

(2) Network-based signal registration management

This is achieved by registering instances through the discovery interface of CloudClient. In this way, richer information can be added, such as 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. Increase the safety stop function

Internal principle: 1) execute the pre-stop method of the plug-in; 2) wait for 10 seconds; 3) execute the stop method of the plug-in. Taking the Solon cloud plug-in as an example, the current service will be unregistered through the discovery interface during pre-stop, so that the discovery system will have 10 seconds to notify each consumer.

In this way, the project based on the discovery service can achieve the effect of non-perceptual update.

  • Enable the ability to stop eyes safely
//通过 enableSafeStop 特性,开启安全停止能力
Solon.start(TestApp.class, args, app -> app.enableSafeStop(true));
  • Configure the number of seconds to wait or delay
solon.stop.delay=10

3. Add log interface components and connect to CloudLogService

The solon.logging and solon.logging.impl log components based on the Slf4j interface are added to provide a unified interface for cloud log services; at the same time, it is also convenient for users to switch to third-party log service components. (Currently water-solon-plugin has been adapted to CloudLogService to provide cloud logging and query services)

  • Features: Enhanced TagsMDC, conducive to the solidification and storage of log meta-information, and later query
@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);
    }
}

  • Log console output example
[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:[...]}}
  • Custom log adder example

Write code

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 家族的一员
//

Configure and use

solon.logging.appender:
  test: #添加器名字,与getName() 对应起来
    class: webapp.demox_mlog.TestAppender #添加器的实现类
    level: TRACE #添加器接收的日志级别(TRACE、DEBUG、INFO、WARN、ERROR)
    enable: true #默认为开启

In small and medium traffic projects, it can be stored in RDB (compared to HBase and ES, which is much cheaper). When writing, it is recommended to use the memory queue to transfer and then write to RDB in batches. Structure can refer to:

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;

For implementation, please refer to CloudLogServiceImp of water-solon-plugin

  • Log adder situation

Introduce solon.logging.impl, add built-in by default: LogConsoleAppender (default level: TRACE)

Introduce solon.cloud, add by default: CloudLogAppender (default level: INFO, and forward data to CloudLogService)

Level control and startup status can be performed through the following configuration:

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

Attachment: Getting started example

Guess you like

Origin www.oschina.net/news/131461/solon-rpc-1-3-7-released