为什么要微服务?
随着业务的发展,一体化架构在技术和管理上都会面临很多挑战,微服务就是为了更好地解决这些问题。
微服务化时的几点建议
- 服务内高内聚,服务间低耦合
- 服务拆分粒度可以先粗一些,后面再细化
- 逐步拆分,先拆分比较独立的非核心服务,先拆分更被依赖的服务
微服务带来的挑战
- 服务治理
- 服务故障
- 服务监控和分布式追踪工具
RPC框架
RPC框架封装了网络调用的细节,让你像调用本地服务一样调用远程服务。
要想保证RPC框架的性能,可以从网络传输和序列化两方面来考虑。
网络传输:
- 选择高性能的I/O模型
- 调试网络参数,比如开启tcp_nodelay
序列化:
- 时间效率和空间效率
- 是否支持跨语言、跨平台
如果对于性能要求不高,可以使用JSON;如果对于性能要求较高,可以使用Thrift或Protobuf.
注册中心
有了注册中心之后,服务节点的变更对客户端就是透明的,方便我们动态地变更服务节点,实现graceful shutdown等功能。
服务节点探活有两种方式:
- 注册中心主动探测
- 服务节点心跳机制
主动探测不方便、成本高,一般的,我们使用心跳机制。
分布式追踪
分布式追踪用于问题排查、性能优化、调用链展示、服务依赖分析等。
一般的,注意以下技术点的使用:
- traceId + spanId
- 切面编程
- 日志采样
- ElasticSearch
负载均衡
负载均衡指的是将请求均衡地分配到不同服务节点中,避免单一节点流量过高或过低。同时,负载均衡可以起到对请求方屏蔽服务节点的部署细节,方便实现动态扩缩容。
负载均衡可以分为两大类:
- 代理类负载均衡
- 客户端负载均衡
代理类负载均衡以单独的服务方式部署,所有请求都要先经过这个服务,由这个服务选择合适的服务节点做流量的分发。
LVS(Linux Virtual Server)和Nginx是代理类负载均衡的范例。LVS工作在OSI模型的第四层传输层,Nginx工作在OSI模型的第七层应用层。对于大流量场景,可以同时部署LVS和Nginx来做HTTP应用服务的负载均衡,即在入口处部署LVS将流量分发到多个Nginx服务器上,再由Nginx服务器分发到应用服务器上。如果流量没有很大,也可以只通过Nginx做负载均衡,降低系统复杂度。
客户端负载均衡一般结合注册中心来使用,注册中心提供服务节点的列表,客户端拿到列表之后使用内嵌的负载均衡服务选择合适的节点做流量的分发。
负载均衡策略可以分为两大类:
- 静态策略
- 动态策略
静态策略在选择服务节点时不会参考后端服务的实际运行状态,常见的静态策略包括:
- 轮询策略(RoundRobin, RR)
- 带有权重的轮询策略
- 哈希算法
- 随机选取
动态策略在选择服务节点时会参考后端服务的负载特性,选择负载最小、资源最空闲的服务来调用。
如何保证Nginx中配置的服务节点是可用的呢?可以通过nginx_upstream_check_module做服务探活,这个模块可以让Nginx定期地探测后端服务的一个指定的接口,根据接口返回的状态码来判断服务是否存活。当探测不存活次数达到一定阈值时,就自动将这个服务节点从负载均衡服务器中摘除。这种服务探活功能还可以用于Web服务的优雅关闭,通过修改探活接口返回的状态码来控制服务是否对外可用。
API网关
API网关可以分为两类:
- 入口网关
- 出口网关
入口网关部署在负载均衡服务器和应用服务器之间,可以提供以下功能:
- 应用服务统一接入地址,对客户端屏蔽不同应用服务的协议细节
- 客户端认证和授权,对应用服务屏蔽不同客户端的认证细节
- 服务限流、降级、熔断
- 设备、IP等黑白名单
出口网关部署在应用服务器和第三方系统之间,功能相对简单,主要用于对调用外部系统的API做统一的认证、授权以及审计等。
API网关需要注意的技术点:
- I/O模型
- 扩展性,比如,责任链模式
- 线程池,注意线程隔离或线程保护
多活
什么是多活?多活指的是在不同的IDC机房中部署多套服务,这些服务共享同一份业务数据,并且都可以承接来自用户的流量。
多活主要的难点在于跨机房数据传输导致的延迟对系统功能和性能的影响。
跨机房数据传输延迟时间:北京同城双机房延迟一般是1ms~3ms;北京和天津双机房延迟一般是10ms;北京和上海双机房延迟一般是30ms;北京和广州双机房延迟一般是50ms;国内和美国西海岸双机房延迟一般是100ms~200ms
同城多活相对简单,可以允许有跨机房数据写入的发生,数据的读取和服务的调用应当尽量保证在同一个机房中。
异地多活比较复杂,需要避免跨机房数据写入,涉及用户分片等问题。