Anatomy of envoy proxy: the architecture of envoy and how it works

Anatomy of envoy proxy: the architecture of envoy and how it works

Envoy has become more and more popular, the basic functionality is quite similar to Nginx, working as a high performace Web server, proxy. But Enovy imported a lot of features that was related to SOA or Microservice like Service Discovery, Circuit Breaker, Rate limiting and so on.

A lot of developers know the roles envoy plays, and the basic functionality it will implement, but don’t know how it organize the architecture and how we understand its configuration well. For me, it’s not easy to understand envoy’s architecture and its configuration since it has a lot of terminology, but if the developer knew how the user traffic goes, he could understand the design of envoy.

Read more

Istio Version Control On Kubernetes

Istio has been adopted as a common implementation of service mesh, since more and more companies want to bring Istio into production, the version control of Istio seems a significant problem to solve.

Version control is necessary as Istio components can be treated as the equivalent RPC services like our business services, we need to have an understanding of which version we are using now and what does the next version bring. And some Istio components can cooperate with the others, if we need to upgrade one component we need to upgrade the other components too.

Although the Istio community provides the Istio upgrade method, we don’t actually want to upgrade such a whole thing in one move, it influences so much that we don’t want to risk.

Read more
再见,micro: 迁移go-micro到纯gRPC框架

再见,micro: 迁移go-micro到纯gRPC框架

micro是基于golang的微服务框架,之前华尔街见闻架构升级中谈到了我们是基于go-micro的后端架构,随着我们对服务网格的调研、测试和实施,为了打通不同语言之间的服务调用,我们选择了gRPC作为服务内部的通用协议。

go-micro框架的架构非常具有拓展性,它拥有自己的RPC框架,通过抽象codec,transport,selector等微服务组件,你既可以使用官方实现的各种插件go-plugins进行组装,又可以根据实际的情况实现自己的组件。然而,我们打算利用服务网格的优势,将微服务的基础组件下沉到基础设施中去,将组件代码从代码库中剥离开来。

这样一来,我们相当于只需要最简的RPC框架,只需要服务之间有统一、稳定、高效的通信协议,由于micro在我们新架构中略显臃肿,于是我们选择逐渐剥除micro。还有一个重要原因,我们选择的服务网格方案是istio,它的代理原生支持gRPC,而micro只是将gRPC当做transport层,相当于复写了gRPC的服务路由逻辑,这样有损于istio的一些特性,譬如流量监控等功能。

出于这些考虑,第一步需要将micro改成纯gRPC模式,这里的改造部分我们考虑只应该去更改基础库的代码,而尽量不要使业务代码更改,减少对已有逻辑的影响,和一些软性的譬如开发人员的工作量。

Read more
微服务实践四: 配置管理

微服务实践四: 配置管理

配置涵盖程序运行的环境,程序依赖的基础资源地址,程序的行为等。

需求

  • 根据环境读取配置
  • 方便更新配置
  • 基础数据格式为listmap等,常见的配置格式是JSONYAMLXML
Read more

微服务实践三: 服务编排

物理机部署

传统发布流程(以Java spring boot为例)

  • 编译jar包
  • 分发到服务器A,B,C
  • 服务启动,监听到指定端口
  • 配置负载均衡到已启动服务端口
  • 服务发布成功

关于服务更新,为了实现滚动更新,可以让LB绑定的服务逐渐更新

传统更新流程

  • 编译jar包
  • 分发到服务器A,B,C
  • 将服务器A从LB上解绑,更新服务器A上的服务
  • 启动服务,通过健康检查和QA之后,将服务器A绑定到LB上
  • 继续更新服务器B和C
  • 服务完全更新成功

拓容流程

  • 新增机器节点
  • 启动jar包
  • 将新节点注册到LB上

特点

  • 单机端口有限,同一个服务如果在同一个服务器更新,需要不同的端口
  • 动态更新LB
  • 拓容成本高

服务化部署(这里以kubernetes为例)

k8s发布流程

  • 构建docker镜像
  • 创建deployment和service,可以限制服务的CPU、Memory等资源,k8s寻找空闲节点启动服务
  • 更新iptables将物理机上指定端口路由到VIP(虚拟服务IP)
  • 绑定物理机端口到LB

k8s更新流程

  • 构建docker镜像
  • 更新deployment和service,k8s更新某个pod
  • 轮流更新pod,直到所有pod更新完成

k8s拓容

  • 寻找空闲节点启动服务,直到达到指定数量

特点

  • 几乎无物理端口限制(k8s需要物理端口作为转发,默认为30000+,数量有限)
  • 服务间通信,可以使用serviceName或者服务的VIP进行访问,内网访问更方便
  • 虚拟化物理机资源,隔离物理资源的细节,资源控制如拓容、服务资源限制方便

Kubernetes vs Docker swarm

  • 稳定性上,k8s上基于iptables的网络路由比docker swarm的网络更加稳定
  • 配置性上,k8s比docker swarm要复杂,swarm采用manager-worker架构,由manager调度worker,docker 1.12以上对于swarm原生支持,方便启动集群,不过k8s在新版本之后也越来越易于配置
  • 管理系统上,swarm比k8s的UI界面更友好,操作性更强

微服务架构下的应用

  • 外部访问可以暴露gateway到LB上,外部通过访问LB进行访问
  • 使用k8s或者swarm,服务间通信可以使用serviceName进行访问,也可以利用容器的IP,使用服务注册进行服务查询
  • 自动拓容,当检测到服务的CPU和内存利用率升高,通过水平拓展,增加服务节点;服务压力减少后,逐渐减少服务节点数量

微服务实践二: 服务容错与降级

保证系统能稳定地运行在生产环境是第一要务,就算是服务质量下降,只要仍在工作,那就是万幸。

常见服务问题

  1. 服务超时
    依赖的第三方服务因为某种不可抗力超时了?数据库慢查询拖垮了整个数据库?

  2. 服务错误
    某个服务挂了?

  3. 服务负载高
    突然陡增的访问量?

解决方法

  1. 限时
    针对服务超时,可以通过超时控制保证接口的返回,可以通过设置超时时间为1s,尽快返回结果,因为大多数情况下,接口超时一方面影响用户体验,一方面可能是由于后端依赖出现了问题,如负载过高,机器故障等。某个互联网公司曾经说,当系统故障时,fail fast。

  2. fallback
    有些情况下,即使服务出错,对用户而言,也希望是透明的,无感的,设置一些fallback,做一些服务降级,保证用户的体验,即使这个服务实际上是挂掉的,返回内容是空的或者是旧的,在此故障期间,程序员能赶紧修复,对用户几乎没有造成不良体验。

  3. 电路熔断
    这里的电路熔断是对于后端服务的保护,当错误、超时、负载上升到一定的高度,那么负载再高下去,对后端来说肯定是无法承受,好像和电路熔断一样,这三个因素超过了阈值,客户端就可以停止对后端服务的调用,这个保护的措施,帮助了运维人员能迅速通过增加机器和优化系统,帮助系统度过难关。

工具

Hystrix能保护客户端,服务降级,它的dashboard上有一句标语,defend your app,确实,当后端程序能对异常,超时,错误等进行处理,那么客户端能获得的数据能更加稳定统一,同时它也是对后端服务的保护,hystrix有上述的电路熔断机制和用户可以自定义fallback,对服务限时等功能。

hystrix运行流程可见How it works
How-it-works

以构建一个对内部RPC调用的HystrixCommand为例:

  1. 构建一个HystrixCommand用于RPC调用,设置超时时间为1s,fallback为返回空数据
  2. 如果缓存打开,结果优先从缓存中获取
  3. 如果电路被熔断,尝试fallback
  4. 如果并发量超过限制,尝试fallback
  5. 不然,运行实际的RPC调用,如果调用失败或者超时,尝试fallback

根据实际情况设置

hystrix的超时时间,fallback,并发量都可以根据需要封装的指令进行设置,可以说非常灵活,根据自己的具体业务进行合适的设置,能优化用户体验。

例如:文章列表API依赖的服务超时,可以通过服务降级拉取缓存中的旧数据进行返回,虽然即时性稍逊,但是起码用户能读到几分钟前的文章,在此期间,赶紧修复问题。

微服务实践一: 架构图谱

微服务实践一: 架构图谱

目录

  1. 服务拆分与服务发现
  2. 微服务框架选择
  3. 服务间通信
  4. 服务编排
  5. 配置管理
  6. 服务容错与降级
  7. 监控
    • API监控
    • 服务调用链
    • 服务负载
    • 基础依赖监控
  8. 日志分析

Monolithic vs Microservice

Monolithic Microservice
开发测试 Java类语言项目越大,运行调试需要越多的编译时间,本地调试有较多依赖,况且业务复杂后不易新人上手 只有部分功能的代码,运行更快速,根据业务划分,方便新人上手
部署 更新整个项目 更新一个微服务
生产调试 日志集中,调试方便 日志分散,服务依赖复杂;拓容简便

这两种架构视乎业务的复杂程度和代码量的大小,复杂程度低于一定程度,还是单一应用开发更快速,部署更加容易,因为服务拆分和线上的调试这些都是需要成本,反之,当业务不断增加,代码不断膨胀,服务拆分显得逐渐重要,公共功能能抽出来做成基础服务,各个业务所需的轮子也不需要重新造一遍,反而节省了开发成本,同时对于新人的加入,由于服务职责单一,让新人进来一个一个服务地熟悉,好过于一个大而全的项目。

微服务基础架构

部署架构

处理流程

  1. 浏览器发起下单请求到负载均衡(LB)
  2. 负载均衡派发请求到API gateway
  3. API gateway查询服务发现,找到user服务和store服务,将用户信息和商品ID发送给store服务,
  4. store服务查询MySQL,找到商品信息,生成订单信息,将请求发送给payment服务
  5. payment服务根据用户指定的支付渠道,向第三方服务发起请求,存储订单信息,并返回订单状态
  6. store服务 -> API gateway -> LB
  7. LB返回数据到浏览器

微服务技术

技术图谱

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×