共计 4859 个字符,预计需要花费 13 分钟才能阅读完成。
Dubbo+Kryo 实现高速序列化
-
Dubbo RPC 是 Dubbo 体系中最外围的一种 高性能, 高吞吐量 的近程调用形式, 是一种 多路复用的 TCP 长连贯调用:
- 长连贯: 防止每次调用新建 TCP 连贯, 进步调用的响应速度
- 多路复用: 单个 TCP 连贯可交替传输多个申请和响应的音讯, 升高了连贯的等待时间, 从而缩小了同样并发数的状况下网络连接数, 进步了零碎的云吞吐量
- Dubbo RPC 次要用于两个 Dubbo 之间的近程调用, 适宜高并发, 小数据的互联网场景.序列化 对于近程调用的响应速度, 吞吐量, 网络带宽耗费等同样也起着至关重要的作用, 是晋升分布式系统性能的最关键因素之一
-
Dubbo 中反对的序列化形式:
- dubbo 序列化: 阿里的高效 java 序列化实现
- hessian2 序列化: hessian是一种高效 跨语言 的二进制序列化形式. 这里不是原生的 hessian2 序列化, 而是阿里批改过的 hessian lite, 是 Dubbo RPC 默认启动的序列化形式
-
json 序列化: 目前有两种实现 -
- 采纳阿里的 fastjson 库
- 采纳 dubbo 中实现的简略 json 库
- json 这种文本序列化性能不如 dubbo 序列化,hessian2 序列化这两种二进制序列化
- java 序列化: 次要采纳 JDK 自带的 Java 序列化实现, 性能差
-
序列化形式:
- 针对 Java 语言的序列化形式:Kryo,FST
-
跨语言的序列化形式:Protostuff,ProtoBuf,Thrift,Avro,MsgPack
序列化: 1. 序列化(serialization)在计算机科学的材料解决中,是指将数据结构或物件状态转换成可取用格局(例如存成档案,存于缓冲,或经由网络中传送),以留待后续在雷同或另一台计算机环境中,能复原原先状态的过程。按照序列化格局从新获取字节的后果时,能够利用它来产生与原始物件雷同语义的正本。2. 简略的来讲就是将某种数据结构或者对象转换成一种数据格式,数据格式能够通过网络传送或者存入数据库中,同时能够依据数据格式还原出原来的数据结构(反序列化)。在 Java 中,对象只有在 JVM 运行时才会存在,如果想要把对象存储到本地或者发送到近程的服务器,则必须通过序列化将对象转换成相应的字节而后进行存储或者传送,之后再将字节组装成对象。3. 在以下场景中都会遇到序列化:3.1 将对象状态保留到文件或者数据库中 3.2 通过 socket 在网络中传送对象 3.3 通过 RMI(近程办法调用)传输对象
-
在面向生产的环境中, 应用 Dubbo+Kryo 实现序列化:
-
引入 Kryo 依赖 kryo-serializers
<dependency> <groupId>de.javakaffee</groupId> <artifactId>kryo-serializers</artifactId> <version>0.42</version> </dependency>
-
配置文件中减少配置
dubbo.protocol. serialization=kryo
-
注册被序列化类
-
要让 Kryo 施展高性能, 须要将须要被序列化的实体类注册到 Dubbo 零碎中, 实现如下回调接口:
public class SerializationOptimizerImpl implements SerializationOptimizerImpl{public Collection<class> getSerializableClasses(){List<Class> classes=new LinkedList<class>(); classes.add(provider.class); classes.add(consumer.class); return classes; } }
-
配置文件中减少配置
dubbo.protocol.optimizer=com.oxford.SerializationOptimizerImpl
- 注册这些类后, 序列化的性能大大晋升, 特地是针对小数量的嵌套对象
1. 为什么须要手动注册, 不在配置文件中注册? 因为要注册的类往往数量较多, 导致配置文件简短 在没有好的 IDE 反对下, 配置文件的编写和重构都比 Java 类简单得多 这些注册的类个别是不须要在我的项目编译打包后还须要动静批改的 2. 为什么不必 @annotation 标注而后零碎发现并注册? 因为 annotation 只能用来标注你能够批改的类, 很多序列化的类是无奈批改的(第三方库,JDK 零碎和其它我的项目的类) 3. 除了 annotation, 能够用其它形式来主动注册被序列化的类, 如扫描门路, 主动发现实现 Serializable 接口 (甚至包含 Externalizable) 的类并注册, 类门路上找到 Serializable 类可能十分多, 能够用 package 前缀来肯定水平限定扫描范畴 在主动注册机制中, 要保障服务提供端和生产端以同样的程序 (或者 ID) 来注册类, 防止错位. 因为可 被发现而后注册的类的数量可能都是不一样的
-
-
- == 留神:==(无参构造函数 和Serializable 接口)
- 如果被序列化的类, 不蕴含无参构造函数, 则会导致 Kryo 序列化性能升高. 因为底层将会应用 Java 的序列化来通明取代 Kryo 序列化.尽可能为每一个被序列化的类增加无参构造函数(Java 类如果不自定义构造函数, 默认就有无参构造函数)
-
Kryo 和 FST 都不须要被序列化类实现 Serializable 接口, 但还是 须要每个序列化类都去实现 Serializable 接口, 放弃和 Java 序列化以及 dubbo 序列化兼容性
Dubbo+Hystrix 实现服务熔断
-
熔断器:
- 在微服务架构中, 依据业务拆分成一个个的服务, 服务服务之间通过 RPC 互相调用
- 为了保障高可用, 单个服务采纳集群部署, 因为网络或者本身的起因, 服务不能保障 100% 可用
- 如果单个服务呈现问题, 调用这个服务就会呈现呈现线程阻塞, 此时若大量的申请涌入,servlet 容器的线程就会被耗费结束, 导致服务瘫痪, 服务与服务之间的依赖性会导致故障流传, 进而导致整个微服务瘫痪, 这就是 ” 服务雪崩效应 ”
- 为了解决服务雪崩效应, 提出熔断器的模型
-
熔断器模型:
- 底层的服务呈现故障, 会导致连锁故障
- 当对特定服务调用的不可用达到一个阈值(Hystrix 默认 5 秒 20 次), 熔断器就会被关上
-
熔断器关上后, 为了防止连锁故障, 通过 fallback 办法间接返回一个固定值
Dubbo Provider 中应用熔断器
- 在 Provider(服务提供者)中减少依赖 spring-cloud-starter-netflix-hystrix
- 在主类中标注 @EnableHystrix 注解
-
在接口实现类的服务 调用办法 上标注 @HystrixCommand 注解, 调用 Hystrix 代理
能够在 @HystrixCommand 中的 @HystrixProperty 中配置阈值
Dubbo Consumer 中应用熔断器
- 在 Consumer(服务消费者)中减少依赖 spring-cloud-starter-netflix-hystrix
- 在主类上标注 @EnableHystrix 注解
- 在调用类 controller 中的调用办法上标注 @HystrixCommand(fallback=” 熔断返回页面的办法名 ”)
-
Dubbo+Hystrix 熔断器仪表盘
在 Provider 和 Consumer 中都须要配置 Hystrix 仪表盘, 配置形式统一
Dubbo+Hystrix 配置熔断器仪表盘
- 减少 Hystrix 仪表盘依赖 spring-cloud-starter-netflix-hystrix-dashboard
- 在主类上标注 @EnableHystrixDashboard 注解开启 Hystrix 仪表盘性能
-
创立 hystrix.stream(监控门路)的 Servlet 配置
@Configuration public class HystrixDashBoardConfiguration{ @Bean public ServletRegistrationBean getServlet(){HystrixMetricsStreamServlet streamServlet=new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean=new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/hystrix.stream"); registrationBea.setName("HystrixMetricsStreamServlet"); return registrationBean; } }
Hystrix 阐明
触发 fallback 办法
参数 形容 FAILURE 执行抛出异样 TIMEOUT 执行开始, 但没有在指定的工夫内实现 SHORT_CIRCUITED 断路器关上, 不尝试执行 THREAD_POOL_REJECTED 线程池回绝, 不尝试执行 SEMAPHORE_REJECTED 信号量回绝, 不尝试执行 fallback 办法抛出异样
参数 形容 FALLBACK_FAILURE Fallback 执行抛出出错 FALLBACK_REJECTED Fallback 信号量回绝, 不尝试执行 FallBack_MISSING 没有 Fallback 实例 Hystrix 罕用配置信息
超时工夫(默认 1000ms)
- hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 在 Consumer 中配置,Provider 的所有办法的超时工夫都是该值, 优先级低于上面的指定配置
-
hystrix.command.HystrixCommandKey.execution.isolation.thread.timeoutInMilliseconds: 在 Consumer 中配置,Provider 的指定办法 (HystrixCommandKey 办法名) 的超时工夫都是该值
线程池外围线程数
- hystrix.threadpool.default.coreSize: 默认为 10,Consumer 中配置
-
Queue:
- hystrix.threadpool.default.maxQueueSize: 最大排队长度, 默认 -1, 应用 SynchronousQueue, 其余值应用LinkedBlockingQueue. 如果要从 - 1 换成其余值重启, 即该值不能动静调整, 须要应用下边这个配置
-
hystrix.threadpool.default.queueSizeRejectionThreshold: 排队线程数量阈值, 默认为 5, 达到时回绝, 如果配置了该选项, 队列的大小是该队列(== 留神:== 如果 maxQueueSize=- 1 的话, 则该选项不起作用)
断路器
- hystrix.command.default.circuitBreaker.requestVolume.Threshold: 当在配置工夫窗口内达到此数量的失败后, 进行短路, 默认 20 个
- hystrix.command.default.circuitBreaker.sleepWindowinMilliseconds: 短路肯定的工夫开始尝试是否复原, 默认 5s
-
hystrix.command.default.circuitBreaker.errorThresholdPercentage: 出错百分比阈值, 当达到此阈值后, 开始短路, 默认 50%
fallback
- hystrix.command.default.fallback.isloation.semaphore.maxConcurrentRequests: 调用线程 (Consumer) 容许申请 HystrixCommand.GetFallback()最大数量, 默认为 10.(== 留神:== 该项配置对于 THREAD 隔离模式也失效)