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 的服务发现。服务提供者使用 原生SDK、OpenAPI、或一个独立的Agent TODO注册 Service 后,服务消费者可以使用DNS TODO 或HTTP&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地图
- 特性大图:要从功能特性,非功能特性,全面介绍我们要解的问题域的特性诉求
- 架构大图:通过清晰架构,让您快速进入 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环境,请确保是在以下版本环境中安装使用:
- 64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux/Unix/Mac。
- 64 bit JDK 1.8+;下载 & 配置。
- 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
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会发现服务列表里已经有了这个服务
访问http://localhost:8761/hi?msg=nacos成功返回
至此一个服务提供者就成功了。
启动一个 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得到结果如下
这个例子中我们注入了一个 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);
}
}
启动服务以后再多启动一个服务提供者以便测试负载均衡:
访问http://localhost:8763/hi:刷新可以见到端口号在一直切换
关于 Nacos Starter 更多的配置项信息
更多关于 spring-cloud-starter-alibaba-nacos-discovery 的 starter 配置项如下所示:
配置项 | Key | 默认值 | 说明 |
---|---|---|---|
服务端地址 | spring.cloud.nacos.discovery.server-addr | 无 | Nacos Server 启动监听的ip地址和端口 |
服务名 | spring.cloud.nacos.discovery.service | ${spring.application.name} | 给当前的服务命名 |
服务分组 | spring.cloud.nacos.discovery.group | DEFAULT_GROUP | 设置服务所处的分组 |
权重 | spring.cloud.nacos.discovery.weight | 1 | 取值范围 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 | 无 | 常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。 |
AccessKey | spring.cloud.nacos.discovery.access-key | 无 | 当要上阿里云时,阿里云上面的一个云账号名 |
SecretKey | spring.cloud.nacos.discovery.secret-key | 无 | 当要上阿里云时,阿里云上面的一个云账号密码 |
Metadata | spring.cloud.nacos.discovery.metadata | 无 | 使用Map格式配置,用户可以根据自己的需要自定义一些和服务相关的元数据信息 |
日志文件名 | spring.cloud.nacos.discovery.log-name | 无 | |
集群 | spring.cloud.nacos.discovery.cluster-name | DEFAULT | 配置成Nacos集群名称 |
接入点 | spring.cloud.nacos.discovery.enpoint | UTF-8 | 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址 |
是否集成Ribbon | ribbon.nacos.enabled | true | 一般都设置成true即可 |
是否开启Nacos Watch | spring.cloud.nacos.discovery.watch.enabled | true | 可以设置成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 客户端发送的心跳包,用于判断机器是否在线。
- 监控 (单机和集群聚合):通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。
- 规则管理和推送:统一管理推送规则。
- 鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。
注意: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 默认不会在各实例之间共享,这一块需要自行改造。
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 中。
然后重启项目。
我们测试一下sentinel的流控功能:
我们对hi这个接口增加了QPS限制,一秒请求超过一次,我们看看会发生什么?
连续刷新我们的请求:http://localhost:8763/hi
被我们之前编写的熔断器中断了。
至此我们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实例。在这里,您可以在发送下游请求之前或之后修改请求和响应。
工作流程
客户端向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
http://localhost:8765/hello-spring-cloud-alibaba-nacos-feign-consumer/hi
得到这样的结果证明我们目前至少没有问题。但是我们发现,这个利用服务名去调用的方式实在太坑,太长,不方便啊。这是我们在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
http://localhost:8765/fegin/hi
这样一对比,显然,第二种更好一些。
类似的配置还有很多,就不一一列举,谓词以及过滤器都还有很多的用法,有兴趣的可以自己查看 gateway 官网
附录:更多配置项
Name | Default | Description |
---|---|---|
spring.cloud.gateway.default-filters | List of filter definitions that are applied to every route. | |
spring.cloud.gateway.discovery.locator.enabled | false | Flag that enables DiscoveryClient gateway integration. |
spring.cloud.gateway.discovery.locator.filters | ||
spring.cloud.gateway.discovery.locator.include-expression | true | SpEL 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-id | false | Option 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-prefix | The 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://’+serviceId | SpEL expression that create the uri for each route, defaults to: ‘lb://’+serviceId. |
spring.cloud.gateway.enabled | true | Enables gateway functionality. |
spring.cloud.gateway.fail-on-route-definition-error | true | Option 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-key | true | Switch to deny requests if the Key Resolver returns an empty key, defaults to true. |
spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code | HttpStatus to return when denyEmptyKey is true, defaults to FORBIDDEN. | |
spring.cloud.gateway.filter.secure-headers.content-security-policy | default-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-options | nosniff | |
spring.cloud.gateway.filter.secure-headers.disable | ||
spring.cloud.gateway.filter.secure-headers.download-options | noopen | |
spring.cloud.gateway.filter.secure-headers.frame-options | DENY | |
spring.cloud.gateway.filter.secure-headers.permitted-cross-domain-policies | none | |
spring.cloud.gateway.filter.secure-headers.referrer-policy | no-referrer | |
spring.cloud.gateway.filter.secure-headers.strict-transport-security | max-age=631138519 | |
spring.cloud.gateway.filter.secure-headers.xss-protection-header | 1 ; mode=block | |
spring.cloud.gateway.forwarded.enabled | true | Enables the ForwardedHeadersFilter. |
spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping | false | If global CORS config should be added to the URL handler. |
spring.cloud.gateway.globalcors.cors-configurations | ||
spring.cloud.gateway.httpclient.connect-timeout | The connect timeout in millis, the default is 45s. | |
spring.cloud.gateway.httpclient.max-header-size | The max response header size. | |
spring.cloud.gateway.httpclient.max-initial-line-length | The max initial line length. | |
spring.cloud.gateway.httpclient.pool.acquire-timeout | Only for type FIXED, the maximum time in millis to wait for aquiring. | |
spring.cloud.gateway.httpclient.pool.max-connections | Only for type FIXED, the maximum number of connections before starting pending acquisition on existing ones. | |
spring.cloud.gateway.httpclient.pool.max-idle-time | Time in millis after which the channel will be closed. If NULL, there is no max idle time. | |
spring.cloud.gateway.httpclient.pool.max-life-time | Duration after which the channel will be closed. If NULL, there is no max life time. | |
spring.cloud.gateway.httpclient.pool.name | proxy | The channel pool map name, defaults to proxy. |
spring.cloud.gateway.httpclient.pool.type | Type of pool for HttpClient to use, defaults to ELASTIC. | |
spring.cloud.gateway.httpclient.proxy.host | Hostname for proxy configuration of Netty HttpClient. | |
spring.cloud.gateway.httpclient.proxy.non-proxy-hosts-pattern | Regular expression (Java) for a configured list of hosts. that should be reached directly, bypassing the proxy | |
spring.cloud.gateway.httpclient.proxy.password | Password for proxy configuration of Netty HttpClient. | |
spring.cloud.gateway.httpclient.proxy.port | Port for proxy configuration of Netty HttpClient. | |
spring.cloud.gateway.httpclient.proxy.username | Username for proxy configuration of Netty HttpClient. | |
spring.cloud.gateway.httpclient.response-timeout | The response timeout. | |
spring.cloud.gateway.httpclient.ssl.close-notify-flush-timeout | 3000ms | SSL 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-timeout | SSL 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-type | The default ssl configuration type. Defaults to TCP. | |
spring.cloud.gateway.httpclient.ssl.handshake-timeout | 10000ms | SSL handshake timeout. Default to 10000 ms |
spring.cloud.gateway.httpclient.ssl.handshake-timeout-millis | ||
spring.cloud.gateway.httpclient.ssl.key-password | Key password, default is same as keyStorePassword. | |
spring.cloud.gateway.httpclient.ssl.key-store | Keystore path for Netty HttpClient. | |
spring.cloud.gateway.httpclient.ssl.key-store-password | Keystore password. | |
spring.cloud.gateway.httpclient.ssl.key-store-provider | Keystore provider for Netty HttpClient, optional field. | |
spring.cloud.gateway.httpclient.ssl.key-store-type | JKS | Keystore type for Netty HttpClient, default is JKS. |
spring.cloud.gateway.httpclient.ssl.trusted-x509-certificates | Trusted certificates for verifying the remote endpoint’s certificate. | |
spring.cloud.gateway.httpclient.ssl.use-insecure-trust-manager | false | Installs the netty InsecureTrustManagerFactory. This is insecure and not suitable for production. |
spring.cloud.gateway.httpclient.websocket.max-frame-payload-length | Max frame payload length. | |
spring.cloud.gateway.httpclient.websocket.proxy-ping | true | Proxy ping frames to downstream services, defaults to true. |
spring.cloud.gateway.httpclient.wiretap | false | Enables wiretap debugging for Netty HttpClient. |
spring.cloud.gateway.httpserver.wiretap | false | Enables wiretap debugging for Netty HttpServer. |
spring.cloud.gateway.loadbalancer.use404 | false | |
spring.cloud.gateway.metrics.enabled | true | Enables the collection of metrics data. |
spring.cloud.gateway.metrics.tags | Tags map that added to metrics. | |
spring.cloud.gateway.redis-rate-limiter.burst-capacity-header | X-RateLimit-Burst-Capacity | The name of the header that returns the burst capacity configuration. |
spring.cloud.gateway.redis-rate-limiter.config | ||
spring.cloud.gateway.redis-rate-limiter.include-headers | true | Whether or not to include headers containing rate limiter information, defaults to true. |
spring.cloud.gateway.redis-rate-limiter.remaining-header | X-RateLimit-Remaining | The name of the header that returns number of remaining requests during the current second. |
spring.cloud.gateway.redis-rate-limiter.replenish-rate-header | X-RateLimit-Replenish-Rate | The name of the header that returns the replenish rate configuration. |
spring.cloud.gateway.redis-rate-limiter.requested-tokens-header | X-RateLimit-Requested-Tokens | The name of the header that returns the requested tokens configuration. |
spring.cloud.gateway.routes | List of Routes. | |
spring.cloud.gateway.set-status.original-status-header-name | The name of the header which contains http code of the proxied request. | |
spring.cloud.gateway.streaming-media-types | ||
spring.cloud.gateway.x-forwarded.enabled | true | If the XForwardedHeadersFilter is enabled. |
spring.cloud.gateway.x-forwarded.for-append | true | If appending X-Forwarded-For as a list is enabled. |
spring.cloud.gateway.x-forwarded.for-enabled | true | If X-Forwarded-For is enabled. |
spring.cloud.gateway.x-forwarded.host-append | true | If appending X-Forwarded-Host as a list is enabled. |
spring.cloud.gateway.x-forwarded.host-enabled | true | If X-Forwarded-Host is enabled. |
spring.cloud.gateway.x-forwarded.order | 0 | The order of the XForwardedHeadersFilter. |
spring.cloud.gateway.x-forwarded.port-append | true | If appending X-Forwarded-Port as a list is enabled. |
spring.cloud.gateway.x-forwarded.port-enabled | true | If X-Forwarded-Port is enabled. |
spring.cloud.gateway.x-forwarded.prefix-append | true | If appending X-Forwarded-Prefix as a list is enabled. |
spring.cloud.gateway.x-forwarded.prefix-enabled | true | If X-Forwarded-Prefix is enabled. |
spring.cloud.gateway.x-forwarded.proto-append | true | If appending X-Forwarded-Proto as a list is enabled. |
spring.cloud.gateway.x-forwarded.proto-enabled | true | If 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
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,用户可以了解服务和端点之间的拓扑关系,可以查看每个服务/服务实例/端点的指标并设置警报规则。
此外,您可以整合:
- 其他使用SkyWalking本机代理和SDK以及Zipkin,Jaeger和OpenCensus进行的分布式跟踪。
- 其他指标系统,例如Prometheus,Sleuth(Micrometer)。
架构
从逻辑上讲,SkyWalking分为四个部分:探针,平台后端,存储和UI
- 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/
启动 SkyWalking
直接进入bin目录运行startup.bat
访问http://localhost:8080即可进入首页
各服务配置
我们需要使用官方提供的探针为我们达到监控的目的,按照实际情况我们需要实现三种部署方式
- IDEA 部署探针
- Java 启动方式部署探针(我们是 Spring Boot 应用程序,需要使用
java -jar
的方式启动应用) - Docker 启动方式部署探针(暂时没有去做,有兴趣的可以自行测试)
探针文件在下好的agent目录
我们这里使用idea的方式去实现
在我们的项目中新建一个文件夹存放我们的agent文件中的所有文件夹以及文件
在我们所需要的项目中配置修改项目的 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界面可以监控到我们的服务了
包含了我们的各种信息,至此SkyWalking的简直使用以及配置也就是完成了。还有很多本人也还不熟悉,只能是简单会用,在以后的学习中会经常记录下来,并分享。如有不足,还请大家指出。
总结与心得
从网上找了一张图:
这图很清楚的表明SpringCloud已经有很多组件进入了维护期:
Zuul、Ribbon、Hystrix、HystrixDashboard、Turbine、Turbine Stream这些组件都已经进入了维护期。
相比之下,alibaba的很多组件性能更好,感知更快。搭建也更加简单,最主要还是中文文档,这对国内的大多数玩家来说简直就是福音啊。如果之前觉得学习SpringCloud看英文很痛苦甚至不想看的同学来说,现在中文的还不愿意看,那就趁早转行吧。先撸一把文档,再跟着文档动手操作一次,出现的问题再解决,这样我们对每一个组件都至少用过三遍,不说精通,至少能够从0入门了吧。技术是要不断的摸索,不断的实践,不能一直原地踏步。
古人云温故而知新可以为师矣