lagou 爪哇 3-5 spring cloud (下) 笔记

Spring Cloud 高级进阶

微服务监控之 Turbine 聚合监控

参考上⽂Hystrix部分

微服务监控之分布式链路追踪技术 Sleuth + Zipkin

分布式链路追踪技术适⽤场景(问题场景)

场景描述

为了⽀撑⽇益增⻓的庞⼤业务量,我们会使⽤微服务架构设计我们的系统,使得 我们的系统不仅能够通过集群部署抵挡流量的冲击,⼜能根据业务进⾏灵活的扩展。那么,在微服务架构下,⼀次请求少则经过三四次服务调⽤完成,多则跨越⼏⼗ 个甚⾄是上百个服务节点。那么问题接踵⽽来:

1)如何动态展示服务的调⽤链路?(⽐如A服务调⽤了哪些其他的服务---依赖
关系)
2)如何分析服务调⽤链路中的瓶颈节点并对其进⾏调优?(⽐如A—>B—>C,C 服务处理时间特别⻓)
3)如何快速进⾏服务链路的故障发现?

这就是分布式链路追踪技术存在的⽬的和意义

分布式链路追踪技术

如果我们在⼀个请求的调⽤处理过程中,在各个链路节点都能够记录下⽇志,并 最终将⽇志进⾏集中可视化展示,那么我们想监控调⽤链路中的⼀些指标就有希 望了~~~⽐如,请求到达哪个服务实例?请求被处理的状态怎样?处理耗时怎 样?这些都能够分析出来了...

分布式环境下基于这种想法实现的监控技术就是就是分布式链路追踪(全链路追 踪)。

市场上的分布式链路追踪⽅案

分布式链路追踪技术已然成熟,产品也不少,国内外都有,⽐如

Spring Cloud Sleuth + Twitter Zipkin
阿⾥巴巴的“鹰眼”
⼤众点评的“CAT”
美团的“Mtrace”
京东的“Hydra”
新浪的“Watchman”
另外还有最近也被提到很多的Apache Skywalking。

分布式链路追踪技术核⼼思想

本质:记录⽇志,作为⼀个完整的技术,分布式链路追踪也有⾃⼰的理论和概念

微服务架构中,针对请求处理的调⽤链可以展现为⼀棵树,示意如下

上图标识⼀个请求链路,⼀条链路通过TraceId唯⼀标识,span标识发起的请求信 息,各span通过parrentId关联起来

注意:我们往往把Spring Cloud Sleuth 和 Zipkin ⼀起使⽤,把 Sleuth 的数据信 息发送给 Zipkin 进⾏聚合,利⽤ Zipkin 存储并展示数据。

微服务统⼀认证⽅案 Spring Cloud OAuth2 + JWT

第⼆代 Spring Cloud 核⼼组件 (SCA)

第⼀代 Spring Cloud (主要是 SCN)很多组件已经进⼊停更维护模式。

Spring Cloud:Netflix,Spring官⽅,SCA(被Spring官⽅认可) 注意:市场上主要使⽤的还是SCN,SCA⼀套框架的集合

Alibaba 更进⼀步,搞出了Spring Cloud Alibaba(SCA),SCA 是由⼀些阿⾥巴巴 的开源组件和云产品组成的,2018年,Spring Cloud Alibaba 正式⼊住了 Spring Cloud 官⽅孵化器。

  • Nacos(服务注册中⼼、配置中⼼)
  • Sentinel哨兵(服务的熔断、限流等)
  • Dubbo RPC/LB
  • Seata分布式事务解决⽅案

nacos

下载 nacos 编译后压缩包 nacos-server-$version.zip 包。

启动服务器
Linux/Unix/Mac 启动命令(standalone代表着单机模式运行,非集群模式):

sh startup.sh -m standalone

Windows 启动命令(standalone代表着单机模式运行,非集群模式):

cmd startup.cmd -m standalone

保护阈值:可以设置为0-1之间的浮点数,它其实是⼀个⽐例值(当前服务健康实例数/当前服务总实例数)。

保护阈值的意义在于当服务A健康实例数/总实例数 < 保护阈值 的时候,nacos将会把该服务所有的实例信息全部提供给消费者,消费者可能访问到不健康的实例,保证了整个系统的⼀个可⽤。

Nacos 数据模型(领域模型)

Namespace 命名空间、Group 分组、集群这些都是为了进⾏归类管理,把服务和配置⽂件进⾏归类,归类之后就可以实现⼀定的效果,⽐如隔离
⽐如,对于服务来说,不同命名空间中的服务不能够互相访问调⽤

Namespace:命名空间,对不同的环境进⾏隔离,⽐如隔离开发环境、测试环境和⽣产环境
Group:分组,将若⼲个服务或者若⼲个配置集归为⼀组,通常习惯⼀个系统归为⼀个组
Service:某⼀个服务,⽐如简历微服务
DataId:配置集或者可以认为是⼀个配置⽂件

Namespace + Group + Service 如同 Maven 中的GAV坐标,GAV坐标是为了锁定Jar,⼆这⾥是为了锁定服务
Namespace + Group + DataId 如同 Maven 中的GAV坐标,GAV坐标是为了锁定Jar,⼆这⾥是为了锁定配置⽂件

SCA Nacos 服务注册和配置中⼼

Nacos (Dynamic Naming and Configuration Service)是阿⾥巴巴开源的⼀个针对微服务架构中服务发现、配置管理和服务管理平台。
Nacos就是注册中⼼+配置中⼼的组合(Nacos=Eureka+Config+Bus)

官⽹:https://nacos.io 下载地址:https://github.com/alibaba/Nacos

Nacos功能特性

  • 服务发现与健康检查
  • 动态配置管理
  • 动态DNS服务
  • 服务和元数据管理(管理平台的⻆度,nacos也有⼀个ui⻚⾯,可以看到注册的服务及其实例信息(元数据信息)等),动态的服务权重调整、动态服务优雅下线,都可以去做

SCA Sentinel 分布式系统的流量防卫兵

Sentinel是⼀个⾯向云原⽣微服务的流量控制、熔断降级组件。替代Hystrix,针对问题:服务雪崩、服务降级、服务熔断、服务限流。

Sentinel 分为两个部分:
核⼼库:(Java 客户端)不依赖任何框架/库,能够运⾏于所有 Java 运⾏时环
境,同时对 Dubbo / Spring Cloud 等框架也有较好的⽀持。
控制台:(Dashboard)基于 Spring Boot 开发,打包后可以直接运⾏,不需
要额外的 Tomcat 等应⽤容器。

Nacos + Sentinel + Dubbo 三剑合璧

删除OpenFeign 和 Ribbon,使⽤Dubbo RPC 和 Dubbo LB。

SCA ⼩结

1)因为内容重叠,SCA 中的分布式事务解决⽅案 Seata 会在紧接着的Mysql课程中 讲解。 2)SCA实际上发展了三条线

第⼀条线:开源出来⼀些组件 第⼆条线:阿⾥内部维护了⼀个分⽀,⾃⼰业务线使⽤ 第三条线:阿⾥云平台部署⼀套,付费使⽤ 从战略上来说,SCA更是为了贴合阿⾥云。 ⽬前来看,开源出来的这些组件,推⼴及普及率不⾼,社区活跃度不⾼,稳定性 和体验度上仍需进⼀步提升,根据实际使⽤来看Sentinel的稳定性和体验度要好 于Nacos。

作业

编程题:根据如下描述,改造 Spring Cloud(上)的作业,完成以下要求:
1、Eureka 注册中心替换为 Nacos 注册中心
2、Config + Bus 配置中心替换为 Nacos 配置中心
3、Feign 调用 替换为 Dubbo RPC 调用
4、使用 Sentinel 对 GateWay 网关的入口资源进行限流(限流参数自定义并完成测试即可)

注意:所有替换组件使用单节点即可


作业资料说明:
1、提供资料:代码工程、验证及讲解视频。
2、讲解内容包含:题目分析、实现思路、代码讲解。
3、效果展示

这个作业可以根据之前的图进行下列的改造:

首先,保证基本配置不变。比如 nginx 配置依旧得到保留。

第一步: 启用 Nacos 服务端
使用单机模式进行启动 sh startup.sh -m standalone。Nacos 将默认使用 8848 端口.

访问地址为:http://localhost:8848/nacos/

第二步: 集成 Nacos 客户端发现服务配置

lagou-parent 的 pom 文件中引入依赖

    <dependencyManagement/>
        </dependencies/>
        ...
        <!--SCA -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--SCA -->
        </dependencies>
    </dependencyManagement>

在⼯程中注释掉 eureka 客户端相关依赖, 引⼊ nacos客户端依赖

<dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
 </dependency>

bootstrap.yml 新增以下配置

spring:
  cloud:
    nacos:
      discovery:
        # 配置 nacos server地址
        server-addr: 192.168.3.29:8848

然后根据此种方式依次改造 code, email, gateway 和 user 微服务。

【可选操作】这里顺便对 Nacos Server 数据持久化改造, 方便 nacos 服务端每次重启后还得重新进行配置.

  1. 执行项目中的 ${nacoshome}/conf/nacos-mysql.sql SQL 语句。
  2. 修改${nacoshome}/conf/application.properties,增加 Mysql 数据源配置
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?
characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456

第三步: Nacos Nacos 客户端配置集成

  1. 微服务中如何锁定 Nacos Server 中的配置⽂件(dataId)
    通过 Namespace + Group + dataId 来锁定配置⽂件.

目前已知 Namespace 不指定就默认public
Group不指定就默认 DEFAULT_GROUP
dataId 的完整格式如下 ${prefix}-${spring.profile.active}.${file-extension}

先在网页中进行新建配置 lagou-cloud-config.yaml

spring:
  # 1. 数据库配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: YOUR-URL
    username: YOUR-USER-NAME
    password: YOUR-PASSWORD
  # 2. 邮箱配置
  mail:
    ## 发送邮件服务器
    host: YOUR-HOST
    ## 发送邮件的邮箱地址
    username: YOUR-USER-NAME
    ## 客户端授权码,不是邮箱密码,这个在qq邮箱设置里面自动生成的
    password: YOUR-PASSWORD
# 3. 防暴刷配置:限制单个客户端ip最新 X 分钟的请求注册接口不能超过 Y 次
myconfig:
  x: 2
  y: 2
  1. 客户端添加依赖
<dependency>
 <groupId>com.alibaba.cloud</groupId>
 <artifactId>spring-cloud-starter-alibaba-nacos�config</artifactId>
</dependency

和 bootstap.yml 配置

spring:
  cloud:
    nacos:
      config:
        server-addr: ${myServerIp}:8848
        namespace: public
        group: DEFAULT_GROUP
        # 前缀
        prefix: lagou-cloud-config
        # 拓展名,默认为 properties
        file-extension: yaml
  1. 通过@Value读取属性, 通过 @RefreshScope 注解使支持自动刷新.

举例改造 email 服务

package com.lagou.edu.service.impl;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
...
...

@Service
@RefreshScope
public class EmailServiceImpl implements EmailService {

    @Value("${spring.mail.username}")
    private String fromEmailAddress;

    /**
     * @param toEmailAddress 收件人邮箱
     * @param code           几位数的验证码
     */
    @Override
    public void sendSimpleMail(String toEmailAddress, String code) {
        ...
        ...
    }
}

测试验证: email 服务是否可以读取配置.
http://edu.lagou.com:8082/email/acc8226@vip.qq.com/123456

第四步: Sentinel 集成

服务端依旧是通过 java -jar 的方式启动: java -jar ./sentinel-dashboard-1.7.2.jar

  1. 客户端 pom.xml 引用依赖
        <!--Sentinel 核⼼环境 依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
  1. 客户端配置 yml
spring:
  cloud:
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080 # sentinel dashboard/console
        port: 8719 # sentinel会在该端⼝启动http server,那么这样 的话,控制台定义的⼀些限流等规则才能发送传递过来, #如果8719端⼝被占⽤,那么会依次+1
  1. 简单配置流控规则

这里顺便对 Sentinel 进行数据持久化改造【可选操作】

lagou-service-email-degrade-rules

[
    {
        "resource":"/email/acc8226@vip.qq.com/123456",
        "grade":2,
        "count":1,
        "timeWindow":5
    }
]

lagou-service-email-flow-rules

[
  {"resource":"/email/acc8226@vip.qq.com/123456",
  "limitApp":"default",
  "grade":1,
  "count":1,
  "strategy":0,
  "controlBehavior":0,
  "clusterMode":false}
]
<!-- Sentinel⽀持采⽤ Nacos 作为规则配置数据源,引⼊该适配依赖 -->
<dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
spring:
  cloud:
    sentinel:
      datasource:
        # 此处的flow为⾃定义数据源名
        flow: # 流控规则
          nacos:
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            data-id: ${spring.application.name}-flow-rules
            groupId: DEFAULT_GROUP
            data-type: json
            # 类型来⾃RuleType类 流控规则
            rule-type: flow 
        degrade: # 流控规则
          nacos:
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            data-id: ${spring.application.name}-degrade-rules
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

第五步: feign 换成 dubbo

  1. 注释掉父工程的 spring-boot-devtools 依赖
<!--热部署-->
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
</dependency>
  1. 客户端配置

1.创建 lagou-service-dubbo-api 工程. 这里包含了共用的接口.

2.添加dubbo 相关依赖

        <!--spring cloud alibaba dubbo 依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-apache-dubbo-adapter</artifactId>
        </dependency>

3.实现类使用 org.apache.dubbo.config.annotation.Service 注解. 而非spring的注解.

4.yaml 进行配置

dubbo:
  scan:
    # dubbo 服务扫描基准包
    base-packages: com.lagou.edu.service.impl
  protocol:
    # dubbo 协议
    name: dubbo
    # dubbo 协议端⼝( -1 表示⾃增端⼝,从 20880 开始)
    port: -1
  registry:
  # 挂载到 Spring Cloud 的注册中⼼
    address: spring-cloud://192.168.3.29

spring:
  main:
    allow-bean-definition-overriding: true

具体实现:
改造 email 微服务

  1. 删除 feigen 和 robbion 配置. 转用 dubbo 相关配置. 同样需要配置下spring.main.allow-bean-definition-overriding=true
    2.将 EmailService 接口移动至 lagou-sercie-dobbo-api 服务
    3.service 添加 dubbo 的 @Service 注解
    4.配置 bootstrap.yml, 添加以下内容。
# 只提供服务
dubbo:
  scan:
    # 服务扫描基准包
    base-packages: com.lagou.edu.service.impl
  protocol:
    # dubbo 协议
    name: dubbo
    # dubbo 协议端⼝( -1 表示⾃增端⼝,从 20880 开始)
    port: -1
  registry:
    # 挂载到 Spring Cloud 的注册中⼼
    address: spring-cloud://192.168.3.29

改造 code 微服务

  1. 删除 feigen 和 robbion 配置. 转用 dubbo 相关配置. 同样需要配置下spring.main.allow-bean-definition-overriding=true
    2.将 CodeService 接口移动至 lagou-sercie-dobbo-api 服务
    3.service 添加 dubbo 的 @Service 注解
    4.配置 bootstrap.yml, 添加以下内容。
# 只提供服务
dubbo:
  scan:
    # dubbo 服务扫描基准包
    base-packages: com.lagou.edu.service.impl
  protocol:
    # dubbo 协议
    name: dubbo
    # dubbo 协议端⼝( -1 表示⾃增端⼝,从 20880 开始)
    port: 20881
    host: 192.168.3.29
  registry:
    # 挂载到 Spring Cloud 的注册中⼼
    address: spring-cloud://192.168.3.29
  # 还使用服务
  cloud:
    # 订阅服务提供⽅的应⽤列表,订阅多个服务提供者使⽤ "," 连接
    subscribed-services: lagou-service-email,lagou-service-user

验证: 发送验证码的服务是否正常
http://localhost:8081/code/create/acc8226@qq.com

改造 user 微服务

  1. 删除 feigen 和 robbion 配置. 转用 dubbo 相关配置. 同样需要配置下spring.main.allow-bean-definition-overriding=true
    2.将 UserService 接口移动至 lagou-sercie-dobbo-api 服务
  2. service 添加 dubbo 的 @Service 注解
  3. 配置 bootstrap.yml, 添加以下内容。
# 只提供服务
dubbo:
  scan:
    # dubbo 服务扫描基准包
    base-packages: com.lagou.edu.service.impl
  protocol:
    # dubbo 协议
    name: dubbo
    # dubbo 协议端⼝( -1 表示⾃增端⼝,从 20880 开始)
    port: 20882
    host: 192.168.3.29
  registry:
    # 挂载到 Spring Cloud 的注册中⼼
    address: spring-cloud://192.168.3.29
  # 还使用服务
  cloud:
    # 订阅服务提供⽅的应⽤列表,订阅多个服务提供者使⽤ "," 连接
    subscribed-services: lagou-service-code

验证: 注册功能是否好使
http://localhost:8077/user/register/acc8226@qq.com/123456/989410

第六步网关改造

详见第四步提到的 Sentinel 集成方案.

pom 导入 Sentinel 核心依赖

        <!--Sentinel 核⼼环境 依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

bootstrap.yml 需要新增以下配置

spring:
  cloud:
    sentinel:
      transport:
        # sentinel服务端地址
        dashboard: 127.0.0.1:8080
        # sentinel dashboard/console
        port: 8719 # sentinel会在该端⼝启动 http server,那么这样的话,控制台定义的⼀些限流等规则才能发送传递过来,
        # 如果8719端⼝被占⽤,那么会依次 +1
        # 如果发现监听的地址不对的话,可以在sentinel客户端配置中加入客户端ip配置
        # client-ip: 192.168.0.7

测试验证:添加每秒只能访问1次的限制
测试地址:http://edu.lagou.com/api/user/info/5d1ad7d9-53ba-4566-8a39-6a96078545da

参考

nacos 中文官网
https://nacos.io/zh-cn/

SpringCloud、dubbo 和 druid 问题总结 - 星火燎原智勇 - 博客园
https://www.cnblogs.com/liang1101/p/12702631.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容