SpringCloud Alibaba,博文有点长耐心看完不说精通,至少从零搭建没问题了

Spring Cloud Alibaba

简介

​ Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。

主要功能

  • 服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
  • 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
  • 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
  • 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
  • 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。。
  • 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
  • 分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。
  • 阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

已包含的组件

Sentinel

阿里巴巴开源产品,把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Nacos

阿里巴巴开源产品,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

RocketMQ

Apache RocketMQ™ 基于 Java 的高性能、高吞吐量的分布式消息和流计算平台。

Dubbo

Apache Dubbo™ 是一款高性能 Java RPC 框架。

Seata

阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。

Alibaba Cloud OSS

阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。

Alibaba Cloud SchedulerX

阿里中间件团队开发的一款分布式任务调度产品,支持周期性的任务与固定时间点触发任务。

Alibaba Cloud SMS

覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

Nacos

简介

在SpringCloudNetflix阶段,我们使用的是Eureka作为服务注册与发现的服务器,现在我们来换一下,换成Spring Cloud Alibaba 提供的 Nacos 组件替代该方案。先查看一下官网

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

Nacos 的关键特性包括:

  • 服务发现和服务健康监测

    Nacos 支持基于 DNS 和基于 RPC 的服务发现。服务提供者使用 原生SDKOpenAPI、或一个独立的Agent TODO注册 Service 后,服务消费者可以使用DNS TODOHTTP&API查找和发现服务。

    Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。Nacos 支持传输层 (PING 或 TCP)和应用层 (如 HTTP、MySQL、用户自定义)的健康检查。 对于复杂的云环境和网络拓扑环境中(如 VPC、边缘网络等)服务的健康检查,Nacos 提供了 agent 上报模式和服务端主动检测2种健康检查模式。Nacos 还提供了统一的健康检查仪表盘,帮助您根据健康状态管理服务的可用性及流量。

  • 动态配置服务

    动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。

    动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。

    配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。

    Nacos 提供了一个简洁易用的UI (控制台样例 Demo) 帮助您管理所有的服务和应用的配置。Nacos 还提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。

  • 动态 DNS 服务

    动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务。动态DNS服务还能让您更容易地实现以 DNS 协议为基础的服务发现,以帮助您消除耦合到厂商私有服务发现 API 上的风险。

    Nacos 提供了一些简单的 DNS APIs TODO 帮助您管理服务的关联域名和可用的 IP:PORT 列表.

  • 服务及其元数据管理

    Nacos 能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的 metrics 统计数据。

Nacos地图

nacosMap

  • 特性大图:要从功能特性,非功能特性,全面介绍我们要解的问题域的特性诉求
  • 架构大图:通过清晰架构,让您快速进入 Nacos 世界
  • 业务大图:利用当前特性可以支持的业务场景,及其最佳实践
  • 生态大图:系统梳理 Nacos 和主流技术生态的关系
  • 优势大图:展示 Nacos 核心竞争力
  • 战略大图:要从战略到战术层面讲 Nacos 的宏观优势

Nacos概念

NOTE: Nacos 引入了一些基本的概念,系统性的了解一下这些概念可以帮助您更好的理解和正确的使用 Nacos 产品。

服务 (Service)

服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos 支持主流的服务生态,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service.

服务注册中心 (Service Registry)

服务注册中心,它是服务,其实例及元数据的数据库。服务实例在启动时注册到服务注册表,并在关闭时注销。服务和路由器的客户端查询服务注册表以查找服务的可用实例。服务注册中心可能会调用服务实例的健康检查 API 来验证它是否能够处理请求。

服务元数据 (Service Metadata)

服务元数据是指包括服务端点(endpoints)、服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据

服务提供方 (Service Provider)

是指提供可复用和可调用服务的应用方

服务消费方 (Service Consumer)

是指会发起对某个服务调用的应用方

配置 (Configuration)

在系统开发过程中通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进行适配。配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成这个步骤。配置变更是调整系统运行时的行为的有效手段之一。

配置管理 (Configuration Management)

在数据中心中,系统中所有配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动统称为配置管理。

名字服务 (Naming Service)

提供分布式系统中所有对象(Object)、实体(Entity)的“名字”到关联的元数据之间的映射管理服务,例如 ServiceName -> Endpoints Info, Distributed Lock Name -> Lock Owner/Status Info, DNS Domain Name -> IP List, 服务发现和 DNS 就是名字服务的2大场景。

配置服务 (Configuration Service)

在服务或者应用运行过程中,提供动态配置或者元数据以及配置管理的服务提供者。

架构图

基本架构图

更多的自行查阅官网吧!

Nacos 快速开始

0.版本选择

您可以在Nacos的release notes博客中找到每个版本支持的功能的介绍,当前2020年9月5日推荐的稳定版本为1.3.1。

1.预备环境准备

Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos,还需要为此配置 Maven环境,请确保是在以下版本环境中安装使用:

  1. 64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux/Unix/Mac。
  2. 64 bit JDK 1.8+;下载 & 配置
  3. Maven 3.2.x+;下载 & 配置

2.下载源码或者安装包

从 Github 上下载源码方式

git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U  
ls -al distribution/target/

// change the $version to your actual path
cd distribution/target/nacos-server-$version/nacos/bin

下载编译后压缩包方式

您可以从 最新稳定版本 下载 nacos-server-$version.zip 包。

  unzip nacos-server-$version.zip 或者 tar -xvf nacos-server-$version.tar.gz
  cd nacos/bin

3.启动服务器

Linux/Unix/Mac

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

sh startup.sh -m standalone

如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行:

bash startup.sh -m standalone

Windows

启动命令:

startup.cmd -m standalone

或者双击startup.cmd运行文件。

4.访问测试

打开浏览器输入http://localhost:8848/nacos,即可访问服务, 默认密码是nacos/nacos

image-20200905155817950

Spring Cloud Alibaba Nacos Config

Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。

Spring Cloud Alibaba Nacos Config 是 Config Server 和 Client 的替代方案,客户端和服务器上的概念与 Spring Environment 和 PropertySource 有着一致的抽象,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序通过部署管道从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。

快速开始

1、在nacos中添加如下配置

Data ID:    nacos-config.properties

Group  :    DEFAULT_GROUP

配置格式:    Properties

配置内容:   user.name=nacos-config-properties
            user.age=90

注意dataid是以 properties(默认的文件扩展名方式)为扩展名。

2、创建nacos config客户端

pom.xml配置文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
    </parent>
    <groupId>com.wujie</groupId>
    <artifactId>hello-spring-cloud-alibaba-dependencies</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>hello-spring-cloud-alibaba-dependencies</name>
    <description>创建统一的依赖管理</description>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.3.RELEASE</spring-boot.version>
        <!-- Spring Settings -->
        <spring-cloud.version>Hoxton SR8</spring-cloud.version>
        <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
    </properties>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <!-- Compiler 插件, 设定 JDK 版本 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <showWarnings>true</showWarnings>
                </configuration>
            </plugin>

            <!-- 打包 jar 文件时,配置 manifest 文件,加入 lib 包的 jar 依赖 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <addMavenDescriptor>false</addMavenDescriptor>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <configuration>
                            <archive>
                                <manifest>
                                    <!-- Add directory entries -->
                                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                                    <addClasspath>true</addClasspath>
                                </manifest>
                            </archive>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- resource -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
            </plugin>

            <!-- install -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
            </plugin>

            <!-- clean -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
            </plugin>


            <!-- dependency -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
            </plugin>
        </plugins>

        <pluginManagement>
            <plugins>
                <!-- Java Document Generate -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-javadoc-plugin</artifactId>
                    <executions>
                        <execution>
                            <phase>prepare-package</phase>
                            <goals>
                                <goal>jar</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

                <!-- YUI Compressor (CSS/JS压缩) -->
                <plugin>
                    <groupId>net.alchim31.maven</groupId>
                    <artifactId>yuicompressor-maven-plugin</artifactId>
                    <version>1.5.1</version>
                    <executions>
                        <execution>
                            <phase>prepare-package</phase>
                            <goals>
                                <goal>compress</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <encoding>UTF-8</encoding>
                        <jswarn>false</jswarn>
                        <nosuffix>true</nosuffix>
                        <linebreakpos>30000</linebreakpos>
                        <force>true</force>
                        <includes>
                            <include>**/*.js</include>
                            <include>**/*.css</include>
                        </includes>
                        <excludes>
                            <exclude>**/*.min.js</exclude>
                            <exclude>**/*.min.css</exclude>
                        </excludes>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>

        <!-- 资源文件配置 -->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
    </build>

</project>
application.yml
spring:
  application:
    name: nacos-config #需要根据他才能找到对应配置文件
  cloud:
    nacos:
      config:
        server-addr: localhost:8848   #nacos地址
        file-extension: yaml   #文件后缀,默认是properties,自定义的需要配置才能找到正确的配置
  profiles:
    active: develop		#声明配置的环境

在启动类中加入相应的代码获取配置的信息

//当动态配置刷新时,会更新到 Enviroment中,因此这里每隔一秒中从Enviroment中获取配置
//            String userName = applicationContext.getEnvironment().getProperty("user.name");
            String currentEnv = applicationContext.getEnvironment().getProperty("current.env");
//            String userAge = applicationContext.getEnvironment().getProperty("user.age");
//            System.err.println("user name :" + userName + "; age: " + userAge);
            System.out.println(currentEnv);
            TimeUnit.SECONDS.sleep(1);

至此,nacos-config简单的使用就配置成功了。

3、支持自定义 namespace 的配置

首先看一下 Nacos 的 Namespace 的概念, Nacos 概念

用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。

在没有明确使用${spring.cloud.nacos.config.namespace}指定namespace的情况下。默认的是public,如果需要指定,就使用spring.cloud.nacos.config.namespace来指定

spring:
  application:
    name: nacos-config
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
        file-extension: yaml
        namespace: 419519c2-cdfd-4905-b754-9b709313d83f #指定一个命名空间

此外 spring.cloud.nacos.config.namespace 的值是 namespace 对应的 id,id 值可以在 Nacos 的控制台获取。并且在添加配置时注意不要选择其他的 namespae,否则将会导致读取不到正确的配置。

支持自定义 Group 的配置

在没有明确指定 ${spring.cloud.nacos.config.group} 配置的情况下, 默认使用的是 DEFAULT_GROUP 。如果需要自定义自己的 Group,可以通过以下配置来实现:

spring:
  application:
    name: nacos-config
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
        file-extension: yaml
        group: TEST_GROUP  #指定一个组
  profiles:
    active: develop

在添加配置时 Group 的值一定要和 spring.cloud.nacos.config.group 的配置值一致。

还有一些别的特性,感兴趣自己去官网查阅吧

Spring Cloud Alibaba Nacos Discovery

​ 该项目通过自动配置以及其他 Spring 编程模型的习惯用法为 Spring Boot 应用程序在服务注册与发现方面提供和 Nacos 的无缝集成。 通过一些简单的注解,您可以快速来注册一个服务,并使用经过双十一考验的 Nacos 组件来作为大规模分布式系统的服务注册中心。

服务注册发现: Nacos Discovery Starter

​ 服务发现是微服务架构体系中最关键的组件之一。如果尝试着用手动的方式来给每一个客户端来配置所有服务提供者的服务列表是一件非常困难的事,而且也不利于 服务的动态扩缩容。Nacos Discovery Starter 可以帮助您将服务自动注册到 Nacos 服务端并且能够动态感知和刷新某个服务实例的服务列表。除此之外,Nacos Discovery Starter 也将服务实例自身的一些元数据信息-例如 host,port,健康检查URL,主页等-注册到 Nacos

启动一个 Provider 应用

pom.xml配置文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.wujie</groupId>
        <version>0.0.1-SNAPSHOT</version>
        <artifactId>hello-spring-cloud-alibaba-dependencies</artifactId>
    </parent>
    <groupId>com.wujie</groupId>
    <artifactId>hello-spring-cloud-alibaba-nacos-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>hello-spring-cloud-alibaba-nacos-provider</name>
    <description>创建一个nacos服务提供者</description>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.0.RELEASE</version>
                <configuration>
                    <mainClass>
                        com.wujie.hello.spring.cloud.alibaba.nacos.provider.HelloSpringCloudAlibabaNacosProviderApplication
                    </mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
application.yml
server:
  port: 8761

spring:
  application:
    name: hello-spring-cloud-alibaba-nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
management:
  endpoints:
    web:
      exposure:
        include: "*"
在启动类上增加@EnableDiscoveryClient注解
@SpringBootApplication
@EnableDiscoveryClient
public class HelloSpringCloudAlibabaNacosProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(HelloSpringCloudAlibabaNacosProviderApplication.class, args);
    }

}
编写一个TestController测试
@RestController
public class TestController {
    @RequestMapping("/hi")
    public String sayHi(@RequestParam("msg")String msg){
        return "hello nacos discovery "+msg;
    }
}

启动这个项目查看nacos会发现服务列表里已经有了这个服务

image-20200905174453519

访问http://localhost:8761/hi?msg=nacos成功返回

image-20200905174515284

至此一个服务提供者就成功了。

启动一个 Consumer For RestTemplate应用

在这里我们的Consumer需要去消费Provider的服务,所以跟以前一样还是可以使用RestTemplate或者是Fegin的方式。我们先来试试使用RestTemplate+LoadBalanceClient的方式调用

pom.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.wujie</groupId>
        <version>0.0.1-SNAPSHOT</version>
        <artifactId>hello-spring-cloud-alibaba-dependencies</artifactId>
    </parent>
    <groupId>com.wujie</groupId>
    <artifactId>hello-spring-cloud-alibaba-nacos-rest-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>hello-spring-cloud-alibaba-nacos-rest-consumer</name>
    <description>Demo project for Spring Boot</description>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.0.RELEASE</version>
                <configuration>
                    <mainClass>
                        com.wujie.hello.spring.cloud.alibaba.nacos.rest.consumer.HelloSpringCloudAlibabaNacosRestConsumerApplication
                    </mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
application.yml
spring:
  application:
    name: hello-spring-cloud-alibaba-nacos-rest-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
management:
  endpoints:
    web:
      exposure:
        include: "*"
server:
  port: 8762
修改启动类如下
@SpringBootApplication
@EnableDiscoveryClient
public class HelloSpringCloudAlibabaNacosRestConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(HelloSpringCloudAlibabaNacosRestConsumerApplication.class, args);
    }

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}
编写TestController测试类
@RestController
public class TestController {
    @Autowired
    RestTemplate restTemplate;
    @Autowired
    LoadBalancerClient loadBalancerClient;
    @Value("${spring.application.name}")
    private String name;
    @RequestMapping("/hi")
    public String sayHi(){
        ServiceInstance choose = loadBalancerClient.choose("hello-spring-cloud-alibaba-nacos-provider");
        String url = String.format("http://%s:%s/hi?msg=%s",choose.getHost(),choose.getPort(),name);
        System.out.println("request uri:"+url);
        return restTemplate.getForObject(url,String.class);
    }
}

启动这个服务访问http://localhost:8762/hi得到结果如下

image-20200905181324864

这个例子中我们注入了一个 LoadBalancerClient 的实例,并且手动的实例化一个 RestTemplate,同时将 spring.application.name 的配置值 注入到应用中来, 目的是调用 Provider 提供的服务时,希望将当前配置的应用名给显示出来。

至此我们使用RestTemplate调用Provider服务成功。

启动一个 Consumer For Fegin应用

pom.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.wujie</groupId>
        <version>0.0.1-SNAPSHOT</version>
        <artifactId>hello-spring-cloud-alibaba-dependencies</artifactId>
    </parent>
    <groupId>com.wujie</groupId>
    <artifactId>hello-spring-cloud-alibaba-nacos-feign-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>hello-spring-cloud-alibaba-nacos-feign-consumer</name>
    <description>创建基于fegin调用的消费者</description>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.0.RELEASE</version>
                <configuration>
                    <mainClass>
                        com.wujie.hello.spring.cloud.alibaba.nacos.feign.consumer.HelloSpringCloudAlibabaNacosFeignConsumerApplication
                    </mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
application.yml
spring:
  application:
    name: hello-spring-cloud-alibaba-nacos-feign-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
  management:
    endpoints:
      web:
        exposure:
          include: "*"
server:
  port: 8763
在启动类上增加@EnableFeignClients注解
@SpringBootApplication
@EnableFeignClients
public class HelloSpringCloudAlibabaNacosFeignConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(HelloSpringCloudAlibabaNacosFeignConsumerApplication.class, args);
    }

}
编写一个Client接口并加上@FeignClient注解
@FeignClient(value = "hello-spring-cloud-alibaba-nacos-provider")
public interface TestClient {
    @RequestMapping("/hi")
    String sayHi(@RequestParam("msg")String msg);
}
编写TestController
@RestController
public class TestController {
    @Autowired
    TestClient testClient;
    @Value("${spring.application.name}")
    private String name;
    @RequestMapping("/hi")
    public String sayHi(){
        return testClient.sayHi(name);
    }

}

启动服务以后再多启动一个服务提供者以便测试负载均衡:

image-20200907100053046

访问http://localhost:8763/hi:刷新可以见到端口号在一直切换

image-20200907100109392

image-20200907100133255

关于 Nacos Starter 更多的配置项信息

更多关于 spring-cloud-starter-alibaba-nacos-discovery 的 starter 配置项如下所示:

配置项Key默认值说明
服务端地址spring.cloud.nacos.discovery.server-addrNacos Server 启动监听的ip地址和端口
服务名spring.cloud.nacos.discovery.service${spring.application.name}给当前的服务命名
服务分组spring.cloud.nacos.discovery.groupDEFAULT_GROUP设置服务所处的分组
权重spring.cloud.nacos.discovery.weight1取值范围 1 到 100,数值越大,权重越大
网卡名spring.cloud.nacos.discovery.network-interface当IP未配置时,注册的IP为此网卡所对应的IP地址,如果此项也未配置,则默认取第一块网卡的地址
注册的IP地址spring.cloud.nacos.discovery.ip优先级最高
注册的端口spring.cloud.nacos.discovery.port-1默认情况下不用配置,会自动探测
命名空间spring.cloud.nacos.discovery.namespace常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
AccessKeyspring.cloud.nacos.discovery.access-key当要上阿里云时,阿里云上面的一个云账号名
SecretKeyspring.cloud.nacos.discovery.secret-key当要上阿里云时,阿里云上面的一个云账号密码
Metadataspring.cloud.nacos.discovery.metadata使用Map格式配置,用户可以根据自己的需要自定义一些和服务相关的元数据信息
日志文件名spring.cloud.nacos.discovery.log-name
集群spring.cloud.nacos.discovery.cluster-nameDEFAULT配置成Nacos集群名称
接入点spring.cloud.nacos.discovery.enpointUTF-8地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址
是否集成Ribbonribbon.nacos.enabledtrue一般都设置成true即可
是否开启Nacos Watchspring.cloud.nacos.discovery.watch.enabledtrue可以设置成false来关闭 watch

Fegin熔断

Sentinel 适配了 Feign 组件。如果想使用,除了引入 spring-cloud-starter-alibaba-sentinel 的依赖外还需要 2 个步骤:

  • 配置文件打开 Sentinel 对 Feign 的支持:feign.sentinel.enabled=true
  • 加入 spring-cloud-starter-openfeign 依赖使 Sentinel starter 中的自动化配置类生效:

并修改TestClient如下:

@FeignClient(value = "hello-spring-cloud-alibaba-nacos-provider",fallbackFactory = TestClientImpl.class)
public interface TestClient {
    @RequestMapping("/hi")
    String sayHi(@RequestParam("msg")String msg);
}
@Component
public class TestClientImpl implements FallbackFactory<TestClient> {
    @Override
    public TestClient create(Throwable throwable) {
        return new TestClient() {
            @Override
            public String sayHi(String msg) {
                return "hi ,this is err!but you msg = "+msg+"! And you fail reason is "+throwable.getMessage();
            }
        };
    }
}

再次重启项目并停止提供者服务访问http://localhost:8763/hi即可得到下面的熔断后结果:

hi ,this is err!but you msg = hello-spring-cloud-alibaba-nacos-feign-consumer! And you fail reason is com.netflix.client.ClientException: Load balancer does not have available server for client: hello-spring-cloud-alibaba-nacos-provider

Sentinel 控制台

1. 概述

Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。另外,鉴权在生产环境中也必不可少。这里,我们将会详细讲述如何通过简单的步骤就可以使用这些功能。

接下来,我们将会逐一介绍如何整合 Sentinel 核心库和 Dashboard,让它发挥最大的作用。同时我们也在阿里云上提供企业级的控制台:AHAS Sentinel 控制台,您只需要几个简单的步骤,就能最直观地看到控制台如何实现这些功能。

Sentinel 控制台包含如下功能:

注意:Sentinel 控制台目前仅支持单机部署。

2. 启动控制台

2.1 获取 Sentinel 控制台

您可以从 release 页面 下载最新版本的控制台 jar 包。

您也可以从最新版本的源码自行构建 Sentinel 控制台:

  • 下载 控制台 工程
  • 使用以下命令将代码打包成一个 fat jar: mvn clean package
2.2 启动

注意:启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。

使用如下命令启动控制台:

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

其中 -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080

从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel。可以参考 鉴权模块文档 配置用户名和密码。

用户可以通过如下参数进行配置:

  • -Dsentinel.dashboard.auth.username=sentinel 用于指定控制台的登录用户名为 sentinel
  • -Dsentinel.dashboard.auth.password=123456 用于指定控制台的登录密码为 123456;如果省略这两个参数,默认用户和密码均为 sentinel
  • -Dserver.servlet.session.timeout=7200 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,默认为 30 分钟;

同样也可以直接在 Spring properties 文件中进行配置。

注意:部署多台控制台时,session 默认不会在各实例之间共享,这一块需要自行改造。

image-20200907110348432

3. 客户端接入控制台

控制台启动后,客户端需要按照以下步骤接入到控制台。

针对于咱们的微服务,我们使用上面的fegin项目,我们直接在application.yml中加上

spring:
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8080

这里的 spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了一个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。

然后重启项目。

image-20200907114211297

我们测试一下sentinel的流控功能:

image-20200907114303747

我们对hi这个接口增加了QPS限制,一秒请求超过一次,我们看看会发生什么?

连续刷新我们的请求:http://localhost:8763/hi

image-20200907114412078被我们之前编写的熔断器中断了。

image-20200907114505391

至此我们sentinel也成功集成了。

我们使用sentinel进行了熔断,也在控制台进行了流控,都是ok的,还有很多功能,有兴趣可以查阅官方文档

Spring Cloud Gateway

简介

Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.

Spring Cloud Gateway旨在提供一种简单而有效的方法来路由到API,并为它们提供跨领域的关注,例如:安全性,监视/度量和弹性。

在之前我们已经使用过另外一个Zuul网关组件,这里我们就不在多说。

名词

  • Route(路由):它是网关的基本构建单元。它由id、目标uri,谓词集合,过滤器集合组成。如果聚合谓词为true,则匹配路由。
  • Predicate(谓词):这是Java 8函数谓词。输入类型是Spring Framework ServerWebExchange。这使您可以匹配HTTP请求中的所有内容,例如标头或参数。
  • Filter(过滤器):这些是使用特定工厂构造的Spring Framework GatewayFilter实例。在这里,您可以在发送下游请求之前或之后修改请求和响应。

工作流程

image-20200907115846813

​ 客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序通过特定于请求的过滤器链运行请求。筛选器由虚线分隔的原因是,筛选器可以在发送代理请求之前和之后运行逻辑。所有“前置”过滤器逻辑均被执行。然后发出代理请求。发出代理请求后,将运行“后”过滤器逻辑。

在没有端口的路由中定义的URI,HTTP和HTTPS URI的默认端口值分别为80和443。

创建一个gateway的项目

pom.xml文件如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.wujie</groupId>
        <version>0.0.1-SNAPSHOT</version>
        <artifactId>hello-spring-cloud-alibaba-dependencies</artifactId>
    </parent>
    <groupId>com.wujie</groupId>
    <artifactId>hello-spring-cloud-alibaba-nacos-gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>hello-spring-cloud-alibaba-nacos-gateway</name>
    <description>基于gateway创建网关</description>



    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>



    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.0.RELEASE</version>
                <configuration>
                    <mainClass>
                        com.wujie.hello.spring.cloud.alibaba.nacos.gateway.HelloSpringCloudAlibabaNacosGatewayApplication
                    </mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

application.yml

server:
  port: 8765

spring:
  application:
    name: hello-spring-cloud-alibaba-nacos-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      routes:
        - id: fegin
          uri: lb://hello-spring-cloud-alibaba-nacos-feign-consumer
          predicates:
            - Path=/**
        - id: rest
          uri: lb://hello-spring-cloud-alibaba-nacos-rest-consumer
          predicates:
            - Path=/**
      discovery:
        locator:
          lower-case-service-id:management: true
          enabled: true
  endpoints:
    web:
      exposure:
        include: "*"

启动类上增加@EnableDiscoveryClient注解启动项目后,我们访问

http://localhost:8765/hello-spring-cloud-alibaba-nacos-rest-consumer/hi

image-20200907160131037

http://localhost:8765/hello-spring-cloud-alibaba-nacos-feign-consumer/hi

image-20200907160147087

得到这样的结果证明我们目前至少没有问题。但是我们发现,这个利用服务名去调用的方式实在太坑,太长,不方便啊。这是我们在application.yml中修改如下配置

- id: fegin
  uri: lb://hello-spring-cloud-alibaba-nacos-feign-consumer
  predicates:
    - Path=/fegin/**
  filters:
    - StripPrefix=1
- id: rest
  uri: lb://hello-spring-cloud-alibaba-nacos-rest-consumer
  predicates:
    - Path=/rest/**
  filters:
    - StripPrefix=1

再换成以下方式访问:

http://localhost:8765/rest/hi

image-20200907160507090

http://localhost:8765/fegin/hi

image-20200907160527126

这样一对比,显然,第二种更好一些。

类似的配置还有很多,就不一一列举,谓词以及过滤器都还有很多的用法,有兴趣的可以自己查看 gateway 官网

附录:更多配置项

NameDefaultDescription
spring.cloud.gateway.default-filtersList of filter definitions that are applied to every route.
spring.cloud.gateway.discovery.locator.enabledfalseFlag that enables DiscoveryClient gateway integration.
spring.cloud.gateway.discovery.locator.filters
spring.cloud.gateway.discovery.locator.include-expressiontrueSpEL expression that will evaluate whether to include a service in gateway integration or not, defaults to: true.
spring.cloud.gateway.discovery.locator.lower-case-service-idfalseOption to lower case serviceId in predicates and filters, defaults to false. Useful with eureka when it automatically uppercases serviceId. so MYSERIVCE, would match /myservice/**
spring.cloud.gateway.discovery.locator.predicates
spring.cloud.gateway.discovery.locator.route-id-prefixThe prefix for the routeId, defaults to discoveryClient.getClass().getSimpleName() + “_”. Service Id will be appended to create the routeId.
spring.cloud.gateway.discovery.locator.url-expression‘lb://’+serviceIdSpEL expression that create the uri for each route, defaults to: ‘lb://’+serviceId.
spring.cloud.gateway.enabledtrueEnables gateway functionality.
spring.cloud.gateway.fail-on-route-definition-errortrueOption to fail on route definition errors, defaults to true. Otherwise, a warning is logged.
spring.cloud.gateway.filter.remove-hop-by-hop.headers
spring.cloud.gateway.filter.remove-hop-by-hop.order
spring.cloud.gateway.filter.request-rate-limiter.deny-empty-keytrueSwitch to deny requests if the Key Resolver returns an empty key, defaults to true.
spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-codeHttpStatus to return when denyEmptyKey is true, defaults to FORBIDDEN.
spring.cloud.gateway.filter.secure-headers.content-security-policydefault-src ‘self’ https:; font-src ‘self’ https: data:; img-src ‘self’ https: data:; object-src ‘none’; script-src https:; style-src ‘self’ https: ‘unsafe-inline’
spring.cloud.gateway.filter.secure-headers.content-type-optionsnosniff
spring.cloud.gateway.filter.secure-headers.disable
spring.cloud.gateway.filter.secure-headers.download-optionsnoopen
spring.cloud.gateway.filter.secure-headers.frame-optionsDENY
spring.cloud.gateway.filter.secure-headers.permitted-cross-domain-policiesnone
spring.cloud.gateway.filter.secure-headers.referrer-policyno-referrer
spring.cloud.gateway.filter.secure-headers.strict-transport-securitymax-age=631138519
spring.cloud.gateway.filter.secure-headers.xss-protection-header1 ; mode=block
spring.cloud.gateway.forwarded.enabledtrueEnables the ForwardedHeadersFilter.
spring.cloud.gateway.globalcors.add-to-simple-url-handler-mappingfalseIf global CORS config should be added to the URL handler.
spring.cloud.gateway.globalcors.cors-configurations
spring.cloud.gateway.httpclient.connect-timeoutThe connect timeout in millis, the default is 45s.
spring.cloud.gateway.httpclient.max-header-sizeThe max response header size.
spring.cloud.gateway.httpclient.max-initial-line-lengthThe max initial line length.
spring.cloud.gateway.httpclient.pool.acquire-timeoutOnly for type FIXED, the maximum time in millis to wait for aquiring.
spring.cloud.gateway.httpclient.pool.max-connectionsOnly for type FIXED, the maximum number of connections before starting pending acquisition on existing ones.
spring.cloud.gateway.httpclient.pool.max-idle-timeTime in millis after which the channel will be closed. If NULL, there is no max idle time.
spring.cloud.gateway.httpclient.pool.max-life-timeDuration after which the channel will be closed. If NULL, there is no max life time.
spring.cloud.gateway.httpclient.pool.nameproxyThe channel pool map name, defaults to proxy.
spring.cloud.gateway.httpclient.pool.typeType of pool for HttpClient to use, defaults to ELASTIC.
spring.cloud.gateway.httpclient.proxy.hostHostname for proxy configuration of Netty HttpClient.
spring.cloud.gateway.httpclient.proxy.non-proxy-hosts-patternRegular expression (Java) for a configured list of hosts. that should be reached directly, bypassing the proxy
spring.cloud.gateway.httpclient.proxy.passwordPassword for proxy configuration of Netty HttpClient.
spring.cloud.gateway.httpclient.proxy.portPort for proxy configuration of Netty HttpClient.
spring.cloud.gateway.httpclient.proxy.usernameUsername for proxy configuration of Netty HttpClient.
spring.cloud.gateway.httpclient.response-timeoutThe response timeout.
spring.cloud.gateway.httpclient.ssl.close-notify-flush-timeout3000msSSL close_notify flush timeout. Default to 3000 ms.
spring.cloud.gateway.httpclient.ssl.close-notify-flush-timeout-millis
spring.cloud.gateway.httpclient.ssl.close-notify-read-timeoutSSL close_notify read timeout. Default to 0 ms.
spring.cloud.gateway.httpclient.ssl.close-notify-read-timeout-millis
spring.cloud.gateway.httpclient.ssl.default-configuration-typeThe default ssl configuration type. Defaults to TCP.
spring.cloud.gateway.httpclient.ssl.handshake-timeout10000msSSL handshake timeout. Default to 10000 ms
spring.cloud.gateway.httpclient.ssl.handshake-timeout-millis
spring.cloud.gateway.httpclient.ssl.key-passwordKey password, default is same as keyStorePassword.
spring.cloud.gateway.httpclient.ssl.key-storeKeystore path for Netty HttpClient.
spring.cloud.gateway.httpclient.ssl.key-store-passwordKeystore password.
spring.cloud.gateway.httpclient.ssl.key-store-providerKeystore provider for Netty HttpClient, optional field.
spring.cloud.gateway.httpclient.ssl.key-store-typeJKSKeystore type for Netty HttpClient, default is JKS.
spring.cloud.gateway.httpclient.ssl.trusted-x509-certificatesTrusted certificates for verifying the remote endpoint’s certificate.
spring.cloud.gateway.httpclient.ssl.use-insecure-trust-managerfalseInstalls the netty InsecureTrustManagerFactory. This is insecure and not suitable for production.
spring.cloud.gateway.httpclient.websocket.max-frame-payload-lengthMax frame payload length.
spring.cloud.gateway.httpclient.websocket.proxy-pingtrueProxy ping frames to downstream services, defaults to true.
spring.cloud.gateway.httpclient.wiretapfalseEnables wiretap debugging for Netty HttpClient.
spring.cloud.gateway.httpserver.wiretapfalseEnables wiretap debugging for Netty HttpServer.
spring.cloud.gateway.loadbalancer.use404false
spring.cloud.gateway.metrics.enabledtrueEnables the collection of metrics data.
spring.cloud.gateway.metrics.tagsTags map that added to metrics.
spring.cloud.gateway.redis-rate-limiter.burst-capacity-headerX-RateLimit-Burst-CapacityThe name of the header that returns the burst capacity configuration.
spring.cloud.gateway.redis-rate-limiter.config
spring.cloud.gateway.redis-rate-limiter.include-headerstrueWhether or not to include headers containing rate limiter information, defaults to true.
spring.cloud.gateway.redis-rate-limiter.remaining-headerX-RateLimit-RemainingThe name of the header that returns number of remaining requests during the current second.
spring.cloud.gateway.redis-rate-limiter.replenish-rate-headerX-RateLimit-Replenish-RateThe name of the header that returns the replenish rate configuration.
spring.cloud.gateway.redis-rate-limiter.requested-tokens-headerX-RateLimit-Requested-TokensThe name of the header that returns the requested tokens configuration.
spring.cloud.gateway.routesList of Routes.
spring.cloud.gateway.set-status.original-status-header-nameThe name of the header which contains http code of the proxied request.
spring.cloud.gateway.streaming-media-types
spring.cloud.gateway.x-forwarded.enabledtrueIf the XForwardedHeadersFilter is enabled.
spring.cloud.gateway.x-forwarded.for-appendtrueIf appending X-Forwarded-For as a list is enabled.
spring.cloud.gateway.x-forwarded.for-enabledtrueIf X-Forwarded-For is enabled.
spring.cloud.gateway.x-forwarded.host-appendtrueIf appending X-Forwarded-Host as a list is enabled.
spring.cloud.gateway.x-forwarded.host-enabledtrueIf X-Forwarded-Host is enabled.
spring.cloud.gateway.x-forwarded.order0The order of the XForwardedHeadersFilter.
spring.cloud.gateway.x-forwarded.port-appendtrueIf appending X-Forwarded-Port as a list is enabled.
spring.cloud.gateway.x-forwarded.port-enabledtrueIf X-Forwarded-Port is enabled.
spring.cloud.gateway.x-forwarded.prefix-appendtrueIf appending X-Forwarded-Prefix as a list is enabled.
spring.cloud.gateway.x-forwarded.prefix-enabledtrueIf X-Forwarded-Prefix is enabled.
spring.cloud.gateway.x-forwarded.proto-appendtrueIf appending X-Forwarded-Proto as a list is enabled.
spring.cloud.gateway.x-forwarded.proto-enabledtrueIf X-Forwarded-Proto is enabled.

Zipkin链路追踪

使用Zipkin进行链路追踪,在想要追踪的项目里加上依赖,并在配置文件中加入配置

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

并在application.yml中添加配置

zipkin:
  base-url: http://localhost:9411

image-20200907171022532

Apache SkyWalking链路追踪

什么是SkyWalking?

一个开放源代码的可观察性平台,用于收集,分析,聚合和可视化来自服务和云本机基础结构的数据。SkyWalking提供了一种简便的方法来维护您的分布式系统的清晰视图,即使在整个云中也是如此。它是一种现代的APM,专门为基于云的基于容器的分布式系统而设计。

为什么使用SkyWalking

SkyWalking提供了用于在许多不同情况下观察和监视分布式系统的解决方案。首先,与传统方法一样,SkyWalking为服务提供自动仪器代理,例如Java,C#,Node.js,Go,PHP和Nginx LUA。(并呼吁提供Python和C ++ SDK贡献)。在多语言,持续部署的环境中,云原生基础架构变得越来越强大,但也越来越复杂。SkyWalking的服务网格接收器使SkyWalking能够从Istio / Envoy和Linkerd等服务网格框架接收遥测数据,从而使用户能够了解整个分布式系统。

SkyWalking为服务,服务实例,端点提供可观察性功能。服务,实例和端点这些术语在当今到处都有使用,因此值得在SkyWalking的上下文中定义它们的特定含义:

  • Service:表示一组/一组工作负载,这些工作负载为传入请求提供相同的行为。您可以在使用乐器代理或SDK时定义服务名称。SkyWalking也可以使用您在Istio等平台中定义的名称。
  • Service Instance:服务组中的每个单独工作负载都称为实例。就像Kubernetes中的Pod一样,它不必是单个OS进程,但是,如果您使用乐器代理,则实例实际上是一个真正的OS进程。
  • Endpoint:服务中用于传入请求的路径,例如HTTP URI路径或gRPC服务类+方法签名

通过SkyWalking,用户可以了解服务和端点之间的拓扑关系,可以查看每个服务/服务实例/端点的指标并设置警报规则。

此外,您可以整合:

  1. 其他使用SkyWalking本机代理和SDK以及Zipkin,Jaeger和OpenCensus进行的分布式跟踪。
  2. 其他指标系统,例如Prometheus,Sleuth(Micrometer)。

架构

从逻辑上讲,SkyWalking分为四个部分:探针,平台后端,存储和UI

image-20200907185528756

  • Probes 收集数据并重新格式化以符合SkyWalking的要求(不同的探针支持不同的来源)。
  • Platform backend支持数据聚合,分析并推动从探针到UI的流程。该分析包括SkyWalking本机跟踪和度量标准,包括Istio和Envoy遥测在内的第三方,Zipkin跟踪格式等。您甚至可以通过使用针对本机度量标准的Observability Analysis Language和针对扩展度量标准的Meter System来定制聚合和分析。
  • Storage 通过开放/可插入的界面存储SkyWalking数据。您可以选择现有的实现,例如ElasticSearch,H2或由Sharding-Sphere管理的MySQL集群,也可以实现自己的实现。
  • UI一个高度可定制的基于Web的界面,允许SkyWalking最终用户可视化和管理SkyWalking数据。

快速开始

下载

官方已经为我们准备好了编译过的服务端版本,下载地址为 http://skywalking.apache.org/downloads/

image-20200907185802890

启动 SkyWalking

直接进入bin目录运行startup.bat

image-20200907185859130

访问http://localhost:8080即可进入首页

image-20200907185945637

各服务配置

我们需要使用官方提供的探针为我们达到监控的目的,按照实际情况我们需要实现三种部署方式

  • IDEA 部署探针
  • Java 启动方式部署探针(我们是 Spring Boot 应用程序,需要使用 java -jar 的方式启动应用)
  • Docker 启动方式部署探针(暂时没有去做,有兴趣的可以自行测试)

探针文件在下好的agent目录

我们这里使用idea的方式去实现

在我们的项目中新建一个文件夹存放我们的agent文件中的所有文件夹以及文件

image-20200907190323798

在我们所需要的项目中配置修改项目的 VM 运行参数,点击菜单栏中的 Run -> EditConfigurations...,此处我们以 hello-spring-cloud-alibaba-nacos-provider 项目为例,修改参数如下

-javaagent:D:\workspace\hello-spring-cloud-alibaba-dependencies\hello-spring-cloud-external-skywalking\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=nacos-provider
-Dskywalking.collector.backend_service=localhost:11800
  • -javaagent:用于指定探针路径
  • -Dskywalking.agent.service_name:用于重写 agent/config/agent.config 配置文件中的服务名
  • -Dskywalking.collector.backend_service:用于重写 agent/config/agent.config 配置文件中的服务地址

启动项目可以在控制台看见如下日志:

DEBUG 2020-09-07 18:45:47:972 main AgentPackagePath : The beacon class location is jar:file:/D:/workspace/hello-spring-cloud-alibaba-dependencies/hello-spring-cloud-external-skywalking/agent/skywalking-agent.jar!/org/apache/skywalking/apm/agent/core/boot/AgentPackagePath.class. 
INFO 2020-09-07 18:45:47:974 main SnifferConfigInitializer : Config file found in D:\workspace\hello-spring-cloud-alibaba-dependencies\hello-spring-cloud-external-skywalking\agent\config\agent.config. 
18:45:51.274 [SkywalkingAgent-5-GRPCChannelManager-0] DEBUG org.apache.skywalking.apm.dependencies.io.netty.util.internal.logging.InternalLoggerFactory - Using SLF4J as the default logging framework

访问之前编写的测试的url:http://localhost:8081/hi?msg=testSkyWalking

返回到SkyWalking的UI界面可以监控到我们的服务了

image-20200907190815043

image-20200907190848543

image-20200907191056820

包含了我们的各种信息,至此SkyWalking的简直使用以及配置也就是完成了。还有很多本人也还不熟悉,只能是简单会用,在以后的学习中会经常记录下来,并分享。如有不足,还请大家指出。

总结与心得

从网上找了一张图:

image-20200907192329895

这图很清楚的表明SpringCloud已经有很多组件进入了维护期:

image-20200907192437453

image-20200907192450083

Zuul、Ribbon、Hystrix、HystrixDashboard、Turbine、Turbine Stream这些组件都已经进入了维护期。

相比之下,alibaba的很多组件性能更好,感知更快。搭建也更加简单,最主要还是中文文档,这对国内的大多数玩家来说简直就是福音啊。如果之前觉得学习SpringCloud看英文很痛苦甚至不想看的同学来说,现在中文的还不愿意看,那就趁早转行吧。先撸一把文档,再跟着文档动手操作一次,出现的问题再解决,这样我们对每一个组件都至少用过三遍,不说精通,至少能够从0入门了吧。技术是要不断的摸索,不断的实践,不能一直原地踏步。

古人云温故而知新可以为师矣

参考资料

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值