登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
Gitee AI
NEW
我知道了
查看详情
登录
注册
代码拉取完成,页面将自动刷新
捐赠
捐赠前请先登录
取消
前往登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
1
Star
0
Fork
0
ali
/
learn-spring-cloud-alibaba
代码
Issues
0
Pull Requests
0
Wiki
统计
流水线
服务
Gitee Pages
JavaDoc
PHPDoc
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
我知道了,不再自动展开
发行版
最新版
v1.0
1133125
2020-01-08 10:21
对比
学习spring0cloud-alibaba
ali
[TOC] # spring-cloud-alibaba **学习李卫民微服务架构2.ospring-cloud-alibaba** ### 创建工程项目 >创建文件夹hello-spring-cloud-alibaba并使用intelij打开,创建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 http://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.1.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.funtl</groupId> <artifactId>hello-spring-cloud-alibaba</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <url>http://www.funtl.com</url> <modules> <module>hello-spring-cloud-alibaba-dependencies</module> </modules> <properties> <java.version>1.8</java.version> <maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.target>${java.version}</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <licenses> <license> <name>Apache 2.0</name> <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url> </license> </licenses> <developers> <developer> <id>liwemin</id> <name>Lusifer Lee</name> <email>lee.lusifer@gmail.com</email> </developer> </developers> <dependencyManagement> <dependencies> <dependency> <groupId>com.funtl</groupId> <artifactId>hello-spring-cloud-alibaba-dependencies</artifactId> <version>${project.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <profiles> <profile> <id>default</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <spring-javaformat.version>0.0.12</spring-javaformat.version> </properties> <build> <plugins> <plugin> <groupId>io.spring.javaformat</groupId> <artifactId>spring-javaformat-maven-plugin</artifactId> <version>${spring-javaformat.version}</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <includes> <include>**/*Tests.java</include> </includes> <excludes> <exclude>**/Abstract*.java</exclude> </excludes> <systemPropertyVariables> <java.security.egd>file:/dev/./urandom</java.security.egd> <java.awt.headless>true</java.awt.headless> </systemPropertyVariables> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <executions> <execution> <id>enforce-rules</id> <goals> <goal>enforce</goal> </goals> <configuration> <rules> <bannedDependencies> <excludes> <exclude>commons-logging:*:*</exclude> </excludes> <searchTransitive>true</searchTransitive> </bannedDependencies> </rules> <fail>true</fail> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-install-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <configuration> <skip>true</skip> </configuration> <inherited>true</inherited> </plugin> </plugins> </build> </profile> </profiles> <repositories> <repository> <id>spring-milestone</id> <name>Spring Milestone</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>spring-snapshot</id> <name>Spring Snapshot</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-milestone</id> <name>Spring Milestone</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>spring-snapshot</id> <name>Spring Snapshot</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project> ``` ### 创建统一的依赖管理 >创建文件夹hello-spring-cloud-alibaba-dependencies并添加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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.funtl</groupId> <artifactId>hello-spring-cloud-alibaba-dependencies</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <url>http://www.funtl.com</url> <properties> <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version> <spring-cloud-alibaba.version>0.9.0.RELEASE</spring-cloud-alibaba.version> </properties> <licenses> <license> <name>Apache 2.0</name> <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url> </license> </licenses> <developers> <developer> <id>liwemin</id> <name>Lusifer Lee</name> <email>lee.lusifer@gmail.com</email> </developer> </developers> <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> <repositories> <repository> <id>spring-milestone</id> <name>Spring Milestone</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>spring-snapshot</id> <name>Spring Snapshot</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-milestone</id> <name>Spring Milestone</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>spring-snapshot</id> <name>Spring Snapshot</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project> ``` **完成之后别忘记把这个模块添加到上级pom** ` <module>hello-spring-cloud-alibaba-dependencies</module>` ### 创建nacos注册中心 #### nacos主要作用 >服务管理: 实现服务 CRUD,域名 CRUD,服务健康状态检查,服务权重管理等功能 配置管理: 实现配置管 CRUD,版本管理,灰度管理,监听管理,推送轨迹,聚合数据等功能 元数据管理: 提供元数据 CURD 和打标能力 插件机制: 实现三个模块可分可合能力,实现扩展点 SPI 机制 事件机制: 实现异步化事件通知,sdk 数据变化异步通知等逻辑 日志模块: 管理日志分类,日志级别,日志可移植性(尤其避免冲突),日志格式,异常码 + 帮助文档 回调机制: sdk 通知数据,通过统一的模式回调用户处理。接口和数据结构需要具备可扩展性 寻址模式: 解决 ip,域名,nameserver、广播等多种寻址模式,需要可扩展 推送通道: 解决 server 与存储、server 间、server 与 sdk 间推送性能问题 容量管理: 管理每个租户,分组下的容量,防止存储被写爆,影响服务可用性 流量管理: 按照租户,分组等多个维度对请求频率,长链接个数,报文大小,请求流控进行控制 缓存机制: 容灾目录,本地缓存,server 缓存机制。容灾目录使用需要工具 启动模式: 按照单机模式,配置模式,服务模式,dns 模式,或者 all 模式,启动不同的程序 + UI 一致性协议: 解决不同数据,不同一致性要求情况下,不同一致性机制 存储模块: 解决数据持久化、非持久化存储,解决数据分片问题 Nameserver: 解决 namespace 到 clusterid 的路由问题,解决用户环境与 nacos 物理环境映射问题 CMDB: 解决元数据存储,与三方 cmdb 系统对接问题,解决应用,人,资源关系 Metrics: 暴露标准 metrics 数据,方便与三方监控系统打通 Trace: 暴露标准 trace,方便与 SLA 系统打通,日志白平化,推送轨迹等能力,并且可以和计量计费系统打通 接入管理: 相当于阿里云开通服务,分配身份、容量、权限过程 用户管理: 解决用户管理,登录,sso 等问题 权限管理: 解决身份识别,访问控制,角色管理等问题 审计系统: 扩展接口方便与不同公司审计系统打通 通知系统: 核心数据变更,或者操作,方便通过 SMS 系统打通,通知到对应人数据变更 OpenAPI: 暴露标准 Rest 风格 HTTP 接口,简单易用,方便多语言集成 Console: 易用控制台,做服务管理、配置管理等操作 SDK: 多语言 sdk Agent: dns-f 类似模式,或者与 mesh 等方案集成 CLI: 命令行对产品进行轻量化管理,像 git 一样好用 > + 如果使用docker安装参见官网 + 官网下载源码包,此处已经下载到docs文件夹下 + 在bin目录下双击startup.cmd启动 ### 服务注册与发现 >创建一个名为 hello-spring-cloud-alibaba-provider 的服务提供者项目,pom.xml 配置如下: ```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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.funtl</groupId> <artifactId>hello-spring-cloud-alibaba</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> <artifactId>hello-spring-cloud-alibaba-provider</artifactId> <packaging>jar</packaging> <url>http://www.funtl.com</url> <inceptionYear>2018-Now</inceptionYear> <licenses> <license> <name>Apache 2.0</name> <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url> </license> </licenses> <developers> <developer> <id>liwemin</id> <name>Lusifer Lee</name> <email>lee.lusifer@gmail.com</email> </developer> </developers> <dependencies> <!-- Spring Boot Begin --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- Spring Boot End --> <!-- Spring Cloud Begin --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- Spring Cloud End --> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.funtl.spring.cloud.alibaba.provider.ProviderApplication</mainClass> </configuration> </plugin> </plugins> </build> </project> ``` ><module>hello-spring-cloud-alibaba-provider</module> + 配置application.yml ```yaml spring: application: # 服务名 name: service-provider cloud: nacos: discovery: # 服务注册中心(nacos) server-addr: localhost:8848 server: # 服务端口 port: 8070 management: # 端点检查(健康检查) endpoints: web: exposure: include: "*" ``` + 创建主启动类ProviderApplication >通过 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现功能 ```java package com.funtl.spring.cloud.alibaba.provider; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication //开启服务注册发现功能 @EnableDiscoveryClient public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); } } ``` >编写一个 RestController 提供 RESTFul API 用于测试提供者 ```java package com.funtl.spring.cloud.alibaba.provider.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class EchoController { @GetMapping(value = "/echo/{string}") public String echo(@PathVariable String string) { return "Hello Nacos Provider " + string; } } ``` + 启动验证是否成功 >通过浏览器访问 http://localhost:8848/nacos Nacos Server 网址查看是否注册上 >通过浏览器访问 http://localhost:8070/actuator/nacos-discovery进行端点检查 >通过浏览器访问http://localhost:8070/echo/hi >浏览器显示Hello Nacos Provider hi ### 创建服务消费者 >创建一个名为 hello-spring-cloud-alibaba-consumer 的服务消费者项目,pom.xml 配置如下: ```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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.funtl</groupId> <artifactId>hello-spring-cloud-alibaba</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> <artifactId>hello-spring-cloud-alibaba-consumer</artifactId> <packaging>jar</packaging> <url>http://www.funtl.com</url> <inceptionYear>2018-Now</inceptionYear> <licenses> <license> <name>Apache 2.0</name> <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url> </license> </licenses> <developers> <developer> <id>liwemin</id> <name>Lusifer Lee</name> <email>lee.lusifer@gmail.com</email> </developer> </developers> <dependencies> <!-- Spring Boot Begin --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- Spring Boot End --> <!-- Spring Cloud Begin --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- Spring Cloud End --> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.funtl.spring.cloud.alibaba.consumer.ConsumerApplication</mainClass> </configuration> </plugin> </plugins> </build> </project> ``` >主pom文件加入<module>hello-spring-cloud-alibaba-consumer</module> + 配置application.yml ```yaml spring: application: # 服务名 name: service-consumer cloud: nacos: discovery: # 服务注册中心 server-addr: localhost:8848 server: # 服务端口 port: 8080 management: # 端点检查(健康检查) endpoints: web: exposure: include: "*" ``` + 创建主启动类ConsumerApplication,并通过 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现功能 ```java package com.funtl.spring.cloud.alibaba.consumer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } } ``` + 创建一个 Java 配置类,主要作用是为了注入 RestTemplate ```java package com.funtl.spring.cloud.alibaba.consumer.configure; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class ConsumerConfiguration { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } } ``` + 创建控制器 ```java package com.funtl.spring.cloud.alibaba.consumer.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController public class TestController { private final RestTemplate restTemplate; @Autowired public TestController(RestTemplate restTemplate) { this.restTemplate = restTemplate; } @GetMapping(value = "/echo/{str}") public String echo(@PathVariable String str) { // 使用服务名请求服务提供者 return restTemplate.getForObject("http://service-provider/echo/" + str, String.class); } } ``` >登录nacos查看是否注册上 >通过浏览器访问 http://localhost:8080/echo/hi >浏览器输出Hello Nacos Provider hi ### 使用fegin调用取代restTemplate >Feign 是一个声明式的伪 HTTP 客户端,它使得写 HTTP 客户端变得更简单。使用 Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用 Feign 注解和 JAX-RS 注解。Feign 支持可插拔的编码器和解码器。Feign 默认集成了 Ribbon,Nacos 也很好的兼容了 Feign,默认实现了负载均衡的效果 >Feign 采用的是基于接口的注解 >Feign 整合了 Ribbon + 在 hello-spring-cloud-alibaba-consumer 项目中增加 org.springframework.cloud:spring-cloud-starter-openfeign 依赖 ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> ``` + 通过 @EnableFeignClients 注解开启 Feign 功能 ```java package com.funtl.spring.cloud.alibaba.consumer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } } ``` + 创建业务结构,通过 @FeignClient("服务名") 注解来指定调用哪个服务 ```java package com.funtl.spring.cloud.alibaba.consumer.service; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(value = "service-provider") public interface EchoService { @GetMapping(value = "/echo/{string}") String echo(@PathVariable("string") String string); } ``` + 编写控制器 ```java package com.funtl.spring.cloud.alibaba.consumer.controller; import com.funtl.spring.cloud.alibaba.consumer.service.EchoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class TestEchoController { @Autowired private EchoService echoService; @GetMapping(value = "/feign/echo/{str}") public String echo(@PathVariable String str) { return echoService.echo(str); } } ``` + 验证是否成功 >通过浏览器访问 http://localhost:8080/feign/echo/hi >浏览器输出Hello Nacos Provider hi表示成功 > + 配置负载均衡,跳过,普及常用负载均衡策略 ***常见负载均衡策略*** >负载主机可以提供很多种负载均衡方法,也就是我们常说的调度方法或算法 **轮循** Round Robin: 这种方法会将收到的请求循环分配到服务器集群中的每台机器,即有效服务器。如果使用这种方式,所有的标记进入虚拟服务的服务器应该有相近的资源容量 以及负载形同的应用程序。如果所有的服务器有相同或者相近的性能那么选择这种方式会使服务器负载形同。基于这个前提,轮循调度是一个简单而有效的分配请求 的方式。然而对于服务器不同的情况,选择这种方式就意味着能力比较弱的服务器也会在下一轮循环中接受轮循,即使这个服务器已经不能再处理当前这个请求了。 这可能导致能力较弱的服务器超载。 **加权轮循** >Weighted Round Robin: 这种算法解决了简单轮循调度算法的缺点:传入的请求按顺序被分配到集群中服务器,但是会考虑提前为每台服务器分配的权重。管理员只是简单的通过服务 器的处理能力来定义各台服务器的权重。例如,能力最强的服务器 A 给的权重是 100,同时能力最低的服务器给的权重是 50。这意味着在服务器 B 接收到第一个 请求之前前,服务器 A 会连续的接受到 2 个请求,以此类推。 **最少连接数** >Least Connection: 以上两种方法都没有考虑的是系统不能识别在给定的时间里保持了多少连接。因此可能发生,服务器 B 服务器收到的连接比服务器 A 少但是它已经超载,因为 服务器 B 上的用户打开连接持续的时间更长。这就是说连接数即服务器的负载是累加的。这种潜在的问题可以通过 “最少连接数” 算法来避免:传入的请求是根据每 台服务器当前所打开的连接数来分配的。即活跃连接数最少的服务器会自动接收下一个传入的请求。接本上和简单轮询的原则相同:所有拥有虚拟服务的服务器资源 容量应该相近。值得注意的是,在流量率低的配置环境中,各服务器的流量并不是相同的,会优先考虑第一台服务器。这是因为,如果所有的服务器是相同的,那么 第一个服务器优先,直到第一台服务器有连续的活跃流量,否则总是会优先选择第一台服务器。 **最少连接数慢启动时间** >Least Connection Slow Start Time: 对最少连接数和带权重的最小连接数调度方法来说,当一个服务器刚加入线上环境是,可以为其配置一个时间段,在这段时间内连接数是有限制的而且是缓慢 增加的。这为服务器提供了一个‘过渡时间’以保证这个服务器不会因为刚启动后因为分配的连接数过多而超载。这个值在 L7 配置界面设置。 **加权最少连接** >Weighted Least Connection: 如果服务器的资源容量各不相同,那么 “加权最少连接” 方法更合适:由管理员根据服务器情况定制的权重所决定的活跃连接数一般提供了一种对服务器非常 平衡的利用,因为他它借鉴了最少连接和权重两者的优势。通常,这是一个非常公平的分配方式,因为它使用了连接数和服务器权重比例;集群中比例最低的服务器 自动接收下一个请求。但是请注意,在低流量情况中使用这种方法时,请参考 “最小连接数” 方法中的注意事项。 **基于代理的自适应负载均衡** >Agent Based Adaptive Balancing: 除了上述方法之外,负载主机包含一个自适用逻辑用来定时监测服务器状态和该服务器的权重。对于非常强大的 “基于代理的自适应负载均衡” 方法来说,负 载主机以这种方式来定时检测所有服务器负载情况:每台服务器都必须提供一个包含文件,这个文件包含一个 0~99 的数字用来标明改服务器的实际负载情况 (0 = 空前,99 = 超载,101 = 失败,102 = 管理员禁用),而服务器同构 http get 方法来获取这个文件;同时对集群中服务器来说,以二进制文件形式提供自身负载情况也是该服务器工作之一,然而,并没有限制服务器如何计算自身的负载 情况。根据服务器整体负载情况,有两种策略可以选择:在常规的操作中,调度算法通过收集的服务器负载值和分配给该服务器的连接数的比例计算出一个权重比 例。因此,如果一个服务器负载过大,权重会通过系统透明的作重新调整。和加权轮循调度方法一样,不正确的分配可以被记录下来使得可以有效的为不同服务器分 配不同的权重。然而,在流量非常低的环境下,服务器报上来的负载值将不能建立一个有代表性的样本;那么基于这些值来分配负载的话将导致失控以及指令震荡。 因此,在这种情况下更合理的做法是基于静态的权重比来计算负载分配。当所有服务器的负载低于管理员定义的下限时,负载主机就会自动切换为加权轮循方式来分 配请求;如果负载大于管理员定义的下限,那么负载主机又会切换回自适应方式。 **固定权重** >Fixed Weighted: 最高权重只有在其他服务器的权重值都很低时才使用。然而,如果最高权重的服务器下降,则下一个最高优先级的服务器将为客户端服务。这种方式中每个真实服务器的权重需要基于服务器优先级来配置。 **加权响应** >Weighted Response: 流量的调度是通过加权轮循方式。加权轮循中所使用的权重是根据服务器有效性检测的响应时间来计算。每个有效性检测都会被计时,用来标记它响应成功花 了多长时间。但是需要注意的是,这种方式假定服务器心跳检测是基于机器的快慢,但是这种假设也许不总是能够成立。所有服务器在虚拟服务上的响应时间的总和 加在一起,通过这个值来计算单个服务物理服务器的权重;这个权重值大约每 15 秒计算一次。 >源 IP 哈希 >Source IP Hash: 这种方式通过生成请求源 IP 的哈希值,并通过这个哈希值来找到正确的真实服务器。这意味着对于同一主机来说他对应的服务器总是相同。使用这种方式,你不需要保存任何源 IP。但是需要注意,这种方式可能导致服务器负载不平衡 ### 分布式配置中心 >在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件 >Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。 >Spring Cloud Alibaba Nacos Config 是 Spring Cloud Config Server 和 Client 的替代方案,客户端和服务器上的概念与 Spring Environment 和 PropertySource 有着一致的抽象,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序通过部署管道从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。 + 接入配置中心,在service-consumer的pom文件中加入配置中心依赖 ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> ``` >完成上述两步后,应用会从 Nacos Config 中获取相应的配置,并添加在 Spring Environment 的 PropertySources 中。这里我们使用 @Value 注解来将对应的配置注入到 TestEchoController 的 username字段,并添加 @RefreshScope 打开动态刷新功能 ```java package com.funtl.spring.cloud.alibaba.consumer.controller; import com.funtl.spring.cloud.alibaba.consumer.service.EchoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RefreshScope @RestController public class TestEchoController { @Autowired private EchoService echoService; @Value("${user.name}") private String username; @GetMapping(value = "/config") public String config() { return echoService.echo(username); } } ``` >本地resource下的application.yml里面的配置文件转移到nacos的配置列表下 >建立service-consumer-config.yaml ```yaml spring: application: # 服务名 name: service-consumer cloud: nacos: discovery: # 服务注册中心 server-addr: 192.168.141.132:8848 server: # 服务端口 port: 8080 management: # 端点检查(健康检查) endpoints: web: exposure: include: "*" user: name: "灶门炭治郎" ``` >本地修改成bootstrap.yml,并删除application.ym + 本地bootstrap.yml ```yaml spring: application: name: service-consumer-config cloud: nacos: config: file-extension: yaml server-addr: localhost:8848 ``` >通过浏览器访问 http://localhost:8080/config ,浏览器输出如下 >Hello Nacos Provider 灶门炭治郎 >注意: Spring Boot 配置文件的加载顺序,依次为 bootstrap.properties -> bootstrap.yml -> application.properties -> application.yml ,其中 bootstrap.properties 配置为最高优先级 ## sentinel服务熔断 ###什么是服务雪崩 >在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以通过 HTTP/RPC 相互调用,在 Spring Cloud 中可以用 RestTemplate + LoadBalanceClient 和 Feign 来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证 100% 可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet 容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的 “雪崩” 效应。为了解决这个问题,业界提出了 熔断器模型。 >阿里巴巴开源了 Sentinel 组件,实现了熔断器模式,Spring Cloud 对这一组件进行了整合。在微服务架构中,一个请求需要调用多个服务是非常常见的 较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值熔断器将会被打开 熔断器打开后,为了避免连锁故障,通过 fallback 方法可以直接返回一个固定值。 ### 什么是 Sentinel >随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 Sentinel 的特征 丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷(对于突然到来的大量请求,您可以配置流控规则,以稳定的速度逐步处理这些请求,从而避免流量突刺造成系统负载过高)、集群流量控制、实时熔断下游不可用应用等 完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况 广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架 / 库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel 完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等 Sentinel 的主要特性 Sentinel 的开源生态 Sentinel 的组成 核心库(Java 客户端): 不依赖任何框架 / 库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持 >控制台(Dashboard): 基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器 >Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。另外,鉴权在生产环境中也必不可少。这里,我们将会详细讲述如何通过简单的步骤就可以使用这些功能。Sentinel 控制台最少应该包含如下功能 查看机器列表以及健康情况: 收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线。 监控 (单机和集群聚合): 通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。 规则管理和推送: 统一管理推送规则。 >鉴权: 生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制 **官方地址** [Sentinel](https://github.com/alibaba/Sentinel/releases) >此处下载好的jar放在了docs下 >启动 >java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -jar sentinel-dashboard-1.7.1.jar >用户名密码sentinel ### sentinel客户端接入 >如果要在您的项目中引入 Sentinel,需要增加 org.springframework.cloud:spring-cloud-starter-alibaba-sentinel Starter POM + 在consumer的pom中加入 ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> ``` + 修改配置 ```yaml spring: application: # 服务名 name: service-consumer cloud: nacos: discovery: # 服务注册中心 server-addr: localhost:8848 # 熔断限流 sentinel: transport: dashboard: localhost:8080 # 开启 Feign 对 Sentinel 的支持 feign: sentinel: enabled: true server: # 服务端口 port: 8081 management: # 端点检查(健康检查) endpoints: web: exposure: include: "*" user: name: "范冰冰22" ``` + 配置熔断类,编写一个 Feign 接口的实现类并增加 @Component 注解 >在services下创建fallback文件夹,并常见EchoServiceFallback类 ```java package com.funtl.spring.cloud.alibaba.consumer.service.fallback; import com.funtl.spring.cloud.alibaba.consumer.service.EchoService; import org.springframework.stereotype.Component; @Component public class EchoServiceFallback implements EchoService { @Override public String echo(String string) { return "echo fallback"; } } ``` + 修改 Feign 接口,在 @FeignClient 接口上增加 fallback 属性指定熔断类即可 ```java package com.funtl.spring.cloud.alibaba.consumer.service; import com.funtl.spring.cloud.alibaba.consumer.service.fallback.EchoServiceFallback; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(value = "service-provider",fallback = EchoServiceFallback.class) public interface EchoService { /** * 模拟provider * @param string * @return */ @GetMapping(value = "/echo/{string}") String echo(@PathVariable("string") String string); } ``` + 测试熔断 >启动 service-consumer 服务并停止 service-provider 服务,通过浏览器访问 http://localhost:8080/feign/echo/hi >echo fallback
最后提交信息为:
Merge remote-tracking branch 'origin/master'
下载
请输入验证码,防止盗链导致资源被占用
取消
下载
1
https://gitee.com/ssssllll/learn-spring-cloud-alibaba.git
[email protected]
:ssssllll/learn-spring-cloud-alibaba.git
ssssllll
learn-spring-cloud-alibaba
learn-spring-cloud-alibaba
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册