zoukankan      html  css  js  c++  java
  • Java RPC 框架 Solon 1.3.7 发布,增强Cloud接口能力范围

    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("::{}
    {}", 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
    

    附:入门示例

  • 相关阅读:
    java泛型
    枚举类与可变参数
    JAVA反射实现JdbcTemplate中查询方法 返回的结果集自动封装成对应的JAVABean对象
    JAVA反射之内省
    JAVA反射基础
    java反射实现将HashMap中的键值对封装为一个JavaBean对象
    hexo配置发布至ssh非22端口服务器
    Exception -LoggerFactory is not a Logback LoggerContext but Logback is on the classpath
    去重优化
    两个域名指向同一服务器的非80端口
  • 原文地址:https://www.cnblogs.com/noear/p/14462264.html
Copyright © 2011-2022 走看看