总结:微服务

一、Java 应用架构趋势

现状:各种架构风格中,微服务架构仅占 32%,单体架构占比 22%,模块化单体架构占比 13%,SOA 架构占比 12%。

 

二、微服务架构趋势

既然微服务架构占比高一些,我们就来看一下微服务架构的应用趋势。

微服务架构的应用状态

从结果来看,有 44%的人团队已经是完全微服务架构了,还有 44%的团队在向微服务架构迁移。可见,在 Java 行业中,微服务架构是得到大家普遍认可的。

  • 但是这个结果与上面的架构风格占比结果有出入,可能是问卷题目设计问题,或者问题回答者的主观原因,不能够苛求结果准确性。

三、每个应用中微服务的数量

既然是微服务架构,每个应用中服务数量必然超过 1 个。从结果可以看出来,有 54%的应用中少于 10 个服务,还有 22%的应用服务数量超过 20 个。

按照公司规模统计:

按照公司规模维度,越是大公司,每个应用中服务数量越多,结果符合康威定律的。

从大家普遍实践结果看,当团队规模较小时,要尽量减少微服务数量。市面上很多老师会告诉我们,微服务架构要按照业务域拆分,但是你要知道,如果团队规模不大,即使拆分了业务域,可能最终开发调试维护也只有你一个。

四、微服务实现技术

从结果看,SpringBoot 几乎霸占了整个微服务市场。所以,大家在日常工作学习过程中,还是主要看看 SpringBoot 栈吧。

在国内,SpringBoot 技术栈还会细分为 SpringNetflixCloud 栈、SpringAlibabaCloud 栈、SpringBoot+Dubbo 栈等。

不同的技术栈中组件有些差异,所以我们需要掌握的不是简单的应用,还要了解其中的原理。原理掌握了,不同的组价只是在应用层面的差异。

五、启动需要多长时间

可以看到,只有 9%的服务在 1 分钟内启动成功,有 26%的服务启动时间需要 10 分钟以上。

按照公司规模看:

从上图可以看出来,人员规模大于 100 人的公司中,服务启动时间普遍长于少于 100 人的公司。产生这种情况的原因有这么几个:

  1. 公司规模大一些,可能业务复杂一些,服务中的代码、类库更多一些;

  2. 公司规模大一些,依赖的组件更多一些,在服务启动时,需要与各种中间件建立链接,然后彼此交换成功心跳,自然需要时间更多。

采用微服务其中一个好处是服务足够小,启动时间比较少。但是,从上面两个问卷结果来看,普遍情况是启动时间比较长,而且在变得更长。

一、什么是微服务?

微服务是相对于单体服务来说的,即将单体服务按照一定的规则进行拆分,如按照业务类型,如:

单体服务:如hubble-api,hubble-job

微服务:如hubble-biz-cm(配置服务),hubble-biz-host(资产服务)、告警查询服务、告警投递服务、数据统计服务等

进化过程:单体服务 → 部分拆分  →  服务间交互? –> 架构标准化,术语标准化

主要角色:

注册中心,服务提供者,服务消费者

二、微服务 VS 单体服务

1、微服务

优点:

  • 升级部署影响小。升级时,只需要重启本服务即可,如hubble-biz-cm。
  • 服务启动快,开发效率高,故障时间短。
    • 代码量少
    • 由于往往伴随着数据库拆分,因此需要连接的数据库也会变少
  • 低耦合,高内聚
  • 云原生时代(K8S),单体服务注定淘汰
  • 开发简单。针对某块功能开发相对容易,只需要熟悉某个服务代码即可

缺点:

  • 技术组件多,学习成本大
  • 部署进程多,部署复杂,服务之间的调用变的复杂
  • 维护较为困难。需要引入调用链进行监控观测
  • 性能会有所降低。原来方法间调用,变成了进程间调用,需要有一定的网络开销,代码封装的开销

2、单体服务

优点:

  • 升级简单。
  • 技术组件简单,坑比较少,遇到问题排查快,相对可控
  • 服务关系简单,仅有一个进程。

缺点:

  • 随着代码逐渐增加,启动越来越慢,影响开发的心情
    • 越来越多的数据库连接,中间件连接等
    • 越来越多的代码需要编译等
  • 影响巨大
    • 小小的改动升级就会重启整个业务,业务很容易感知到。
      • 比如VPS服务,随便改个功能,启动过程如果有业务申请虚机就歇菜了
    • 服务故障重启时间长,故障恢复慢,甚至轻易不敢去重启
      • 比如VPS服务,启动要接近2分钟,每次升级服务都心惊胆战
  • 扩展性差
    • 增加功能只能在单体项目中加,耦合严重,很容易出问题

三、微服务框架

1、主流Java微服务开发框架

  • Spring Cloud(一直很火)
    • 全家桶。SpringCloud是一系列框架集合。它基于SpringBoot的便利性融合了一整套实现微服务的框架并提供了服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等组件。
  • Dubbo(阿里开源,以前比较火)

2、Spring boot

基于spring boot可快速开发单个微服务。框架的框架,简化配置文件,降低开发难度。

类比:

Spring cloud:互联网

Spring boot:服务器

理念:约定优于配置。目的在于减少软件开发人员所需要做出的决定的数量。

  • 大量使用注解。代替众多的XML配置。(老的Spring使用了大量的XML配置)
  • 默认的加载方式。如数据库连接,配置的方式通过前缀定义即可。
  • 默认内嵌了Tomcat服务器,不用安装tomcat,也不用在启动的时候配置tomcat启动

优点:

  • 提供众多starter,我们只需要在配置文件中配置数据源信息即可。
    • spring-boot-starter-web
    • spring-cloud-starter-eureka:有互联网的能力
    • spring-boot-starter-data-redis
    • spring-boot-starter-aop:切面配置,如加日志,异常处理
    • spring-boot-starter-activemq
    • spring-boot-starter-rocketmq
    • spring-boot-starter-freemarker:自动引入配套的freemarker包
    • mybatis-spring-boot-starter:持久层框架,数据库管理组件
    • druid-spring-boot-starter:数据库连接池
    • spring-boot-starter-actuator:监控组件,自动监控进程相关指标
  • IOC(控制反转):系统自动创建并维护对象,多实例,单实例
  • 内嵌了Web容器(Tomcat、Jetty和Undertow),降低了对环境的要求
  • 搭建快速:直接下载官方包启动即可
  • 配置简化:减少了很多spring的配置文件

3、微服务配套运行环境

K8S

Docker

4、微服务治理Istio

服务网格。它是一组和应用服务部署在一起的轻量级的网络代理。使微服务治理与服务本身解耦。

1、多样化的灰度发布(金丝雀发布);

  • 基于流量:20%流量访问V2,80%流量访问V1
  • 基于用户:zhangsan访问V2,其它访问V1

2、故障注入(类似小鹿乱撞,但场景较少)。支持随机向服务通信中注入故障(如模拟延时/网络中断),检测服务的可靠性;

  • Isito 支持注入两种类型的故障:网络延迟中断
    • 中断是模拟上游服务崩溃的情况,表现为 HTTP 的错误码和 TCP 连接失败。

3、提供非侵入的熔断,超时,重试机制;

4、安全认证。无侵入式地为服务增加认证、鉴权和加密通信的能力。

相关配置

#按照流量比例灰度
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-hubble-biz-host
  namespace: hubble-manager-istio-host
spec:
  gateways: 
    - hubble-gateway
    - mesh
  hosts:
    - istio.hubble.qiyi.domain
    - m-biz-host.hubble-manager-istio-host.svc.cluster.local
  http:
  - match:
    - uri:
        prefix: /api/biz/host
    route:
    - destination:
        host: m-biz-host.hubble-manager-istio-host.svc.cluster.local
        subset: hubble-biz-host-2-2-7-005
      weight: 10
    - destination:
        host: m-biz-host.hubble-manager-istio-host.svc.cluster.local
        subset: hubble-biz-host-2-2-7-006
      weight: 90


#按照用户灰度(比如hubble-query,访问量比较多的组token,可以按照用户升级,好处是方便和业务沟通效果)
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

四、服务注册与发现

1、开源系统

很多系统都会涉及服务注册与发现,如K8S,Promethus,Spring Cloud(eureka),zookeeper、Dubbo,consul

2、角色

服务注册:针对服务提供者。服务提供方将自己调用地址注册到服务注册中心,让服务调用方能够方便地找到自己。

注册中心:中间代理,价值就是管理服务,管理一个健康的服务列表。

服务发现:针对服务消费者。服务调用方从服务注册中心找到自己需要调用的服务的地址。

3、K8S服务注册与发现

3.1、介绍

针对Service资源对象而言。

发现的含义:pod怎么找到另一个pod,并发送请求

3.2、注册与发现流程

注册过程:

  • 通过API创建Service资源对象,并得到ClusterIp
  • CoreDNS 监听 API Server,发现有新建的 Service 对象,则创建一个从 Service 名称与 ClusterIP 的域名映射记录。

发现流程:

  • 服务消费者(POD)向集群 DNS 发出查询,把 Service 名称解析为 ClusterIP(一般也会本地缓存一份配置)
  • 然后服务消费者(POD)将流量发送给ClusterIP 上(最终流量被转发给 Pod 所在节点的网卡)
  • 物理节点Node将ClusterIp的数据转向健康的 Pod

3.3、使用案例

比如prometheus server将告警消息打到alertmanager:http://prometheus-api.qiyi.domain/prometheus/prometheus/

比如prometheus operator ServiceMonitor配置:QKE

3.4、K8S服务注册与发现总结

服务注册:Service

注册中心:DNS

服务发现:服务使用者,如Pod,从注册中心(DNS)拉取服务列表

4、Promethus服务注册与发现

原理:借助第三方服务发现代理,如k8s服务发现,eureka服务发现,consul服务发现

Configuration | Prometheus

K8S(kubernetes_sd_configs):http://prometheus-api.qiyi.domain/prometheus/prometheus/

Promethus服务发现角色总结:

服务注册:无

注册中心:第三方注册中心,如eureka,k8s的Service

服务发现:针对第三方注册中心开发发现逻辑

5、SpringCloud服务注册与发现:eureka

介绍

eureka服务注册与发现组件,是spring cloud推荐的注册中心实现,是分布式开发的核心组件之一

http://10.49.4.119:9500/

架构

高可用(ap)(对比zookeeper(cp))

eureka:集群部署,数据备份,当某个节点挂掉之后,客户端请求会自动切换 到新的Eureka节点;当宕机的服务器重新恢复后,Eureka会再次将其纳入到服务器集群管理之中;

zookeeper:虽然也是集群部署,数据备份,但是zookeeper当集群中只有master提供服务,当master节点挂了之后,会进行重新选举,选举需要花费秒级的时间;

自我保护机制

当Eureka Server节点在短时间内丢失过多的客户端时(可能发送了网络故障),那么这个节点将进入自我保护模式,不再注销任何微服务,当网络故障回复后,该节点会自动退出自我保护模式。

五、Spring cloud其它微服务组件

1、feign

对服务进行声明式调用,封装了接口调用,让接口调用变的简单,代码层面类似于调用方法

普通web调用:

String url = PropKit.get("lingxu-new");

Map<String, String> params = new HashMap<String, String>();

params.put("token", getSysVal("lingxu-api-token"));

params.put("uuid", uuid);

String result = WebUtil.doGet(url, params, 6000060000);

缺点:

  • 无错误检查:如某个参数名称输错了
  • 无熔断,需要配置超时,当调用量大容易影响对方服务
  • 手动输入参数名称
  • 代码复杂,代码可读性差;
  • 逻辑混乱,调用对象不明确

feign调用:

声明:@FeignClient(name = "hubble-biz-aiops")

List<AlarmLevelesVO> list = aiopsAlarmLevelesServiceRemote.getLevelListByEventid(eventid);

Feign优势:

  • 可插拔的注解支持:@FeignClient(name = "hubble-biz-aiops")
  • 支持Hystrix和异常的时候进行Fallback;
  • 整合Ribbon的负载均衡;
  • 支持HTTP请求和响应的压缩

响应压缩配置:

server.compression.enabled=true

server.compression.mime-types=application/json

#默认是2048,即2K

server.compression.min-response-size=2048000

2、ribbon

ribbon 是一个客户端负载均衡器,可类比于nginx的负载均衡模块功能。

服务提供者往往是通过集群部署,ribbon的职责是将请求均匀的转发服务集群中的所有服务器/POD

和nginx区别

nginx:独立的负载均衡服务,消费者与服务提供者的中间组件

ribbon:进程内负载均衡,类库

ribbon负载均衡配置

#开启重试功能

spring.cloud.loadbalancer.retry.enabled=true

#请求连接的超时时间,单位毫秒

ribbon.ConnectTimeout=30000

#请求处理的超时时间, 单位毫秒

ribbon.ReadTimeout=30000

#对所有操作请求都进行重试

ribbon.OkToRetryOnAllOperations=true

#对当前实例的重试次数

ribbon.MaxAutoRetries=0

#最多重试多少台服务器

ribbon.MaxAutoRetriesNextServer=2

3、hystrix

熔断器。

作用:当发现服务提供者有问题时,及时停止调用,避免影响自己和服务提供者。

  • 保护自身:避免本功能占用进程太多线程资源,影响自身稳定性
  • 保护对方:避免发送太多请求,给服务提供者提供太多压力,甚至造成服务提供者卡死的情况
  • 保护调用本服务的客户端:自身出问题可能还会影响调用者

详情见六单独描述

4、fegin - hytrix - ribbon协作流程

5、zuul

作用:网关,参考nginx

  • 现负载均衡、反向代理

对比nginx无优势,性能差不多

6、config

配置中心。

作用:动态更新配置。

当前hubble微服务未使用

7、bus

消息总线。

作用:用于在集群(例如,配置变化事件)中传播状态变化,可与Config联合实现热部署,达到自动化动态更新配置。

8、Spring Cloud Consul

服务注册与发现。

作用:类似Eureka,Eureka2.x已经闭源。

原理:基于Consul,封装了Consul操作

9、Security

安全认证。

如登录系统时的用户名,密码

我们统一使用公司单点登录

六、熔断器 - hystrix

熔断的目的:是为了保证服务高可用。不能因为系统中的一个小服务不可用,从而导致整个系统崩溃。

目标:1、快速失败。2、自愈。

熔断策略

状态:

  • Closed: 关闭状态(断路器关闭),所有请求都正常访问。
  • Open:打开状态(断路器打开),所有请求都会被降级。Hystix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,断路器会完全关闭。默认失败比例的阈值是50%,请求次数最少不低于20次。
  • Half Open:半开状态,Closed状态不是永久的,关闭后会进入休眠时间(默认是5S)。随后断路器会自动进入半开状态。此时会释放部分请求通过,若这些请求都是健康的,则会完全打开断路器,否则继续保持关闭,再次进行休眠计时。

状态切换:

1、当请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open)。这时所有请求会直接失败而不会发送到后端服务。

2、断路器保持在开路状态一段时间后(默认5秒),自动切换到半开路状态(HALF-OPEN)。这时会判断下一次请求的返回情况,如果请求成功,断路器切回闭路状态(CLOSED),否则重新切换到开路状态(OPEN)。

Fallback

Fallback相当于是降级操作。对于重要的查询操作可以将缓存数据返回,让业务无感知。

资源隔离技术

通过线程池实现。每个应用名称对应一个线程池。

#并发执行的最大线程数,默认10

hystrix.threadpool.default.coreSize=50

#BlockingQueue的最大队列数,默认值-1

hystrix.threadpool.default.maxQueueSize=1000

#即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝,默认值5

hystrix.threadpool.default.queueSizeRejectionThreshold=800

#hubble-biz-host

hystrix.threadpool.hubble-biz-host.coreSize=80

hystrix.threadpool.hubble-biz-host.maxQueueSize=1000

hystrix.threadpool.hubble-biz-host.queueSizeRejectionThreshold=800

#hubble-biz-cm

hystrix.threadpool.hubble-biz-cm.coreSize=150

hystrix.threadpool.hubble-biz-cm.maxQueueSize=1000

hystrix.threadpool.hubble-biz-cm.queueSizeRejectionThreshold=800

Hystrix遵循的设计原则总结:

  • 防止任何单独的依赖耗尽资源(线程)
  • 过载立即切断并快速失败,防止排队
  • 尽可能提供回退以保护用户免受故障
  • 使用隔离技术来避免服务间相互影响
  • 通过近实时的指标,监控和告警,确保故障被及时发现
  • 防止整个依赖客户端执行失败,而不仅仅是网络通信
    • 超时
    • 网络故障
    • 服务端500等

七、Hubble-manager微服务架构实践

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值