一、Restlight是什么
ESA Restlight 是一个轻量级、面向 REST 的 Web 框架,支持 SpringMVC 和 JAX-RS 的注释。 参考文档:restlight doc
1.1 线程模型
Restlight由于是使用Netty作为底层HttpServer的实现,因此图中沿用了部分EventLoop的概念,线程模型由了Acceptor,IO EventLoopGroup(IO线程池)以及Biz ThreadPool(业务线程池)组成。
Acceptor: 由1个线程组成的线程池, 负责监听本地端口并分发IO 事件。IO EventLoopGroup: 由多个线程组成,负责读写IO数据(对应图中的read()和write())以及HTTP协议的编解码和分发到业务线程池的工作。Biz Scheduler:负责执行真正的业务逻辑(大多为Controller中的业务处理,拦截器等)。Custom Scheduler: 自定义线程池
二、Restlight常见调优参数
Server相关配置
所有配置均以restlight.server开头, 基于properties的配置(yml以此类推)
| 配置项 | 默认 | 说明 |
|---|---|---|
host | 0.0.0.0 | 服务绑定的ip |
port | 8080 | 服务绑定的端口 |
| unix-domain-socket-file | 不为空则使用Unix Domain Socket绑定到此文件(优先级高于ip:port的方式) | |
| use-native-transports | Linux环境下为true其余为false | 是否使用原生epoll支持, 否则使用NIO的selector |
connector-threads | 1 | 连接线程池大小 |
io-threads | cpu*2(默认不超过64) | IO线程池大小 |
biz-termination-timeout-seconds | 60 | 优雅停机等待超时时间 |
| http2-enable | false | 是否开启Http2(网关配置即可) |
| compress | false | 是否启用HTTP响应压缩(网关配置即可) |
| decompress | false | 是否启用HTTP请求解压 (网关配置即可) |
| max-content-length | 4 * 1024 * 1024 | 最大contentLength限制(b) |
| max-initial-line-length | 4096 | 最大request line限制(b) |
| max-header-size | 8192 | 最大header size限制(b) |
| route.use-cached-routing | true | 开启路由缓存 |
| route.compute-rate | 1 | 路由计算率,取值范围0-1000,固定的概率之下更新路由 |
| warm-up.enable | false | 是否开启服务预热功能 |
| warm-up.delay | 0 | 服务延迟暴露时间(单位:毫秒) |
keep-alive-enable | true | false服务器将强制只支持短链接 |
| soBacklog | 128 | 对应netty的ChannelOption.SO_BACKLOG |
| write-buffer-high-water-mark | -1 | netty中channel的高水位值 |
| write-buffer-low-water-mark | -1 | netty中channel的低水位值 |
idle-time-seconds | 60 | 连接超时时间 |
| logging | 设置LoggingHandler用于打印连接及读写信息 |
核心功能配置
所有配置均以restlight.server开头, 基于properties的配置(yml以此类推)
| 配置项 | 默认 | 说明 |
|---|---|---|
context-path | 全局path前缀 | |
biz-threads.core | cpu*4(默认在64-128之间) | 业务线程池核心线程数 |
biz-threads.max | cpu*6(默认在128-256之间) | 业务线程池最大线程数 |
biz-threads.blocking-queue-length | 512 | 业务线程池阻塞队列大小 |
biz-threads.keep-alive-time-seconds | 180 | 业务线程池keepAliveTime 单位:秒 |
| serialize.request.negotiation | false | 请求序列化协商 |
| serialize.request.negotiation-param | format | 请求序列化协商参数名称 |
| serialize.response.negotiation | false | 响应序列化协商 |
| serialize.response.negotiation-param | format | 响应序列化协商参数名称 |
| print-banner | true | 是否启动打印logo |
SSL配置
所有配置均以restlight.server.ssl开头, 基于properties的配置(yml以此类推)
| 配置项 | 默认 | 说明 |
|---|---|---|
| enable | false | 是否使用https |
| ciphers | 支持的加密套件,不设置表示使用默认 | |
| enable-protocols | 支持的加密协议,不设置表示使用默认 | |
| cert-chain-path | 证书路径,https-enable为true时必须 | |
| key-path | 私钥路径,https-enable为true时必须 | |
| key-password | 私钥文件密钥(如果需要的话) | |
| trust-certs-path | Trust Store | |
| session-timeout | session过期时间, 0表示使用默认 | |
| session-cache-size | session缓存大小, 0表示使用默认 | |
| handshake-timeout-millis | SSL握手超时时间 | |
| client-auth | 客户端认证类型,不设置默认无 |
其他
| 参数 | 作用 |
|---|---|
| 全局path | Restlight支持全局Path,使用时需要做如下配置 restlight.server.context-path=/global-path/ |
| 快速失败 | Restlight 支持根据请求任务的排队时间快速失败。具体地,从接收到首字节(TTFB)或请求任务进入线程池开始排队时开始计时, 如果请求任务真正执行时的时间与起始时间的差值大于指定值(timeout),那么直接结束当前请求(返回500)。使用时,需要配置timeout与起始时间(首字节时间或者开始排队时间,默认后者),示例如下: restlight.server.scheduling.timeout.BIZ.type=QUEUED restlight.server.scheduling.timeout.BIZ.time-millis=30 |
三、Restlight常用功能
| 常用功能 | 作用 |
|---|---|
| 序列化 | 序列化的方法,支持多种序列化方式并存内置pb json等 |
| Filter | 过滤器。所有方法都将会在IO线程上调用,尽量不要阻塞, 否则将对性能会有较大的影响。 |
| Interceptor | 拦截器,例如:实现一个拦截器, 拦截所有Header中包含X-Foo请求头的请求 |
| ExceptionResolver | 全局异常处理器 |
| 参数解析 | 介绍了 一种在restlight里面通过自定义注解获取入参,执行用户自己定义的方法的逻辑 |
| 返回值解析 | 介绍了 一种在restlight里面通过自定义注解获取返回结果,执行用户自己定义的方法的逻辑 |
| ArgumentResolverAdvice | ArgumentResolverAdvice允许用户在ArgumentResolver参数解析器解析参数的前后添加业务逻辑以及修改解析后的参数。主要针对方法的参数 |
| ReturnValueResolverAdvice | ReturnValueResolverAdvice允许用户在ReturnValueResolver参数解析器解析参数的前后添加业务逻辑以及修改解析后的参数。主要针对方法的返回值 |
| 请求参数聚合 | 支持将请求的参数(AsyncRequest AsyncResponse)聚合到Bean中 |
| URL参数聚合 | 支持将Url中的参数与Form表单中的参数(仅当Content-Type为application/x-www-form-urlencoded时有效)聚合到Bean中。 |
| Context Path | Restlight支持全局Path,使用时需要做如下配置:restlight.server.context-path=/global-path/ |
| Aware扩展 | 在Spring场景,Restlight支持通过xxxAware接口获取一些内部对象。其中包含 RestlightBizExecutorAware: 获取业务线程池 RestlightIoExecutorAware: 获取IO线程池 RestlightServerAware: 获取RestlightServer RestlightDeployContextAware: 获取DeployContext |
| Mock测试 | 可以将cotroller纳入单元测试的范畴中,但是一般单元测试用不到。 |
| 辅助配置 | SpringBoot场景下大多数的配置可通过application.properties(或者yaml)配置文件即可完成配置,但是配置文件配置还是会有其缺陷 |
扩展能力
| 扩展能力 | 作用 |
|---|---|
| 新建连接数限制 | 当前服务的新建连接数进行QPS限制。超过连接数限制的请求将被拒绝。当前服务的新建连接数进行QPS限制。超过连接数限制的请求将被拒绝。#开启新建连接数限制restlight.server.ext.connection-creation-limit.enable=true#设置每秒限制4000个新建连接,默认为20000restlight.server.ext.connection-creation-limit.max-per-second=40000 |
| CPU Load保护 | #开启Cpu Load自我保护 restlight.server.ext.cpu-load-protection.enable=true #cpu负载阈值,默认为80.0D cpu超过此负载之后将开始随机丢弃连接 restlight.server.ext.cpu-load-protection.threshold=80.0D #初始连接丢弃率,默认为10.0D(0代表0%, 100代表100%, 可以传小数) restlight.server.ext.cpu-load-protection.initial-discard-rate=10.0D #最大连接丢弃率,默认为80.0D(0代表0%, 100代表100%, 可以传小数) restlight.server.ext.cpu-load-protection.max-discard-rate=80.0D |
| Access Log(重要) | AccessLog拦截器在每个请求结束后记录访问日志,内容包含:客户端地址、请求协议、请求url(不包含路径参数)、请求方法、请求耗时、响应状态码、响应body大小以及访问时间。访问日志默认会打印日志到logs/access.log文件中 #开启AccessLog restlight.server.ext.accesslog.enable=true |
| 跨域 | 开启跨域功能(网关配置即可) restlight.server.ext.cors.enable=true |
| 文件及表单参数解析 | 文件和表单上传 |
| 签名认证(重要) | 使用Restlight参数签名验证拦截器 #开启参数签名验证功能的必需配置 restlight.server.ext.sign.enable=true #调用方ID参数名,默认为appId restlight.server.ext.sign.app-id-name=appId #签名秘钥版本参数名,默认为sv restlight.server.ext.sign.secret-version-name=sv #请求时间戳参数名,默认为ts restlight.server.ext.sign.timestamp-name=ts等等.... |
| XSS过滤 | 配置好后自动对所有请求进行转义或者过滤 #开启Xss过滤 restlight.server.ext.xss.enable=true #Xss过滤模式,默认escape(转义模式),filter为过滤模式 restlight.server.ext.xss.mode=escape |
| IP白名单 | IP白名单拦截器可以过滤非法IP的访问。同时支持IP地址和正则表达式两种匹配方式 #开启IP白名单拦截器的必需配置 restlight.server.ext.whitelist.enable=true #IP白名单列表(多值请用逗号分隔,正则表达式regex:开头) restlight.server.ext.whitelist.ips=10.10.1.1,regex:10.12.* #缓存最近访问的IP地址(默认1024个) restlight.server.ext.whitelist.cache-size=1024 #缓存的失效时间(单位:ms,默认为60s) restlight.server.ext.whitelist.expire=60000 |
| 数据校验(重要) | Restlight集成了Hibernate Validator,提供了开箱即用的数据校验功能,通过注解完成对JavaBean、Controller方法参数和返回值的校验, 并支持异常消息国际化。 |
四、Restlight特性
| 特性 | 作用 |
|---|---|
| 路由缓存 | 请求的路由寻找对应的controller是有缓存的,是按照LRU的二八原则来缓存的,请求得越多的path路由被缓存的就越多 |
五、Restlight Endpoint扩展
Spring Boot Actuator支持 支持自定义Endpoint和独立端口
在Spring Boot Actuator基础之上Restlight提供额外的功能扩展
确保在应用程序的配置文件(如 application.properties 或 application.yml)中启用了 Actuator。可以通过添加以下配置来启用 Actuator:
management.endpoints.web.exposure.include=*
| 特性 | 作用 |
|---|---|
| 查看biz线程池信息——json格式 | curl -X GET localhost:8080/actuator/bizthreadpool |
| 查看biz线程池信息——prometheus格式 | curl -X GET localhost:8080/actuator/bizthreadpool4prometheus |
| 业务线程池扩容 | curl -X POST -H "Content-Type:application/json" -d "{"corePoolSize":"1","maxPoolSize":"2"}" localhost:8080/actuator/bizthreadpool |
| IO线程池Metrics | curl -X GET localhost:8080/actuator/ioexecutor |
| 获取Restlight所有配置信息 | curl -X GET localhost:8080/actuator/restlightconfigs |
| 强制Full GC | curl -X POST localhost:8080/actuator/forcefgc |
| 修改优雅停机等待时间 | curl -X POST -H "Content-Type:application/json" -d "{"timeout": 120}" localhost:8080/actuator/terminationtimeout |
六、Spring MVC支持
ExceptionHandler支持异常处理,全局异常处理
七、Restlight核心
7.1 Restlight Server
esa.restlight.server.Restlite为Restlight架构中的Restlight Server模块的入口类, 在ESA HttpServer 基础上丰富了更多的功能
- 引入业务线程池
- 基于
CompletableFuture的响应式编程支持 - 线程调度
Filter- 请求路由(根据url, method, header等条件将请求路由到对应的Handler)
7.2 Restlight Core
esa.restlight.core.Restlight为Restlight架构中的Restlight Core模块的入口类, 在Restlight Server 基础上丰富了更多的功能
Tags:
ControllerControllerAdviceHandlerInterceptor: 拦截器ExceptionHandler: 全局异常处理器BeanValidation: 参数校验ArgumentResolver: 参数解析扩展ArgumentResolverAdvice: 参数解析扩展ReturnValueResolver: 返回值解析扩展ReturnValueResolverAdvice: 返回值解析扩展RequestSerializer: 请求序列化器(通常负责反序列化Body内容)ResposneSerializer: 响应序列化器(通常负责序列化响应对象到Body)- 内置
Jackson,Fastjson,Gson,ProtoBuf序列化支持 - …
Restlight Core在Restlight Server中Route的业务处理部分做了封装, 完成拦截器,参数绑定,反序列化,返回值解析,序列化等一系列功能。
Restlight Core为核心实现, 实际使用时需配合Restlight SpringMVC以及Restlight JAX-RS实现。
Tip
Restlight Core拥有Restlight Server的所有特性, 具体功能特性请参考Restlight Server部分
由于Restlight Core为标准实现, 需要配合Restlight SpringMVC或者Restlight JAX-RS一起使用
7.3 Restlight for Spring
esa.restlight.spring.Restlight4Spring为Restlight架构中的Restlight for Srping模块的入口类, 在Restlight Core 基础上增强了自动配置功能
Route自动配置Filter自动配置Controller自动配置ControllerAdvice自动配置HandlerInterceptor自动配置ExceptionHandler自动配置ArgumentResolver自动配置ArgumentResolverAdvice自动配置ReturnValueResolver自动配置ReturnValueResolverAdvice自动配置RequestSerializer自动配置ResposneSerializer自动配置Validator自动配置- …
Tip
自动配置是指Restlight4Spring会从ApplicationContext中获取对应类型的bean并配置到Restlight。
八、全链路异步
当前Restlight版本支持Filter , HandlerInterceptor, Controller, ExceptionHandler异步。
对应处理链路
上述对应着一个请求的完成执行链路, 并且每个链路都支持异步。
Restlight保证在框架层面对所有的CompletableFuture处理都不会主动的切换执行的线程
这句话的具体例子在 Restlight 异步保证
九、使用注意
1.Controller 语义不能重复,不要出现相同的path否则会出现随机调用
2.当前版本Restlight会将收到的文件存在内存之中,请勿上传超大文件。