typora-root-url: img
一、SpringCloud介绍
概述:
- Spring Cloud 是一系列框架的有序集合。
- Spring Cloud 并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来。
- 通过 Spring Boot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
- 它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、 断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
- Spring Cloud项目官方网址:https://spring.io/projects/spring-cloud
相关介绍
Spring Cloud 版本命名方式采用了伦敦地铁站的名称,同时根据字母表的顺序来对应版本时间顺序,比如:最早的Release版本:Angel,第二个Release版本:Brixton,然后是Camden、Dalston、Edgware,Finchley,Greenwich,Hoxton。
Spring Cloud 与 Dubbo 对比
- Spring Cloud 与 Dubbo 都是实现微服务有效的工具。
- Dubbo 只是实现了服务治理,而 Spring Cloud 子项目分别覆盖了微服务架构下的众多部件。
- Dubbo 使用 RPC 通讯协议,Spring Cloud 使用 RESTful 完成通信,Dubbo 效率略高于 Spring Cloud。
小结:
Spring 公司将其他公司中微服务架构常用的组件整合起来,并使用 SpringBoot 简化其开发、配置。称为 Spring Cloud。
Spring Cloud 与 Dubbo都是实现微服务有效的工具。Dubbo 性能更好,而 Spring Cloud 功能更全面。
SpringCloud—Eureka组件—注册中心
Eureka
-
Eureka 是 Netflix 公司开源的一个服务注册与发现的组件 。
-
Eureka 和其他 Netflix 公司的服务组件(例如负载均衡、熔断器、网关等) 一起,被 Spring Cloud 社区整合为Spring-Cloud-Netflix 模块。
-
Eureka 包含两个组件:Eureka Server (注册中心) 和 Eureka Client (服务提供者、服务消费者)。
注册中心关系图:
Eureka Demo搭建思路
- 搭建 Provider 和 Consumer 服务。
- 使用 RestTemplate 完成远程调用。
- 搭建 Eureka Server 服务。
- 改造 Provider 和 Consumer 称为 Eureka Client。
- Consumer 服务 通过从 Eureka Server 中抓取 Provider地址 完成 远程调用
1、搭建两个普通的SpringBoot模块
2、不适用Eureka 就只能使用RestTemplate 进行远程调用,需要将地址以字符串形式固定写死
3、引入Eureka注册中心
在服务端的父级模块依赖,pom.xml
<!--spring boot 环境 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<!--spring cloud 版本-->
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<!--引入Spring Cloud 依赖-->
<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>
</dependencies>
</dependencyManagement>
在自身模块中的pom.xml文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- eureka-server 服务端依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
服务端SpringBoot入口启动类:
@SpringBootApplication
// 启用EurekaServer
@EnableEurekaServer
public class EurekaApp {
public static void main(String[] args) {
SpringApplication.run(EurekaApp.class,args);
}
}
服务端 application.xml 配置文件
server:
port: 8761
# eureka 配置
# eureka 一共有4部分 配置
# 1. dashboard:eureka的web控制台配置
# 2. server:eureka的服务端配置
# 3. client:eureka的客户端配置
# 4. instance:eureka的实例配置
eureka:
instance:
hostname: localhost # 主机名
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信
register-with-eureka: false # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要
fetch-registry: false # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要
4、改造 Provider 和 Consumer 称为 Eureka Client。将普通的SpringBoot项目改造为Eureka的客户端,远程调用时,从注册中心动态获取服务端的地址。
provider提供方改动代码:
SpringBoot入口类:
@SpringBootApplication
@EnableEurekaClient // 申明为这事Eureka的客户端
public class ProviderAPP {
public static void main(String[] args) {
SpringApplication.run(ProviderAPP.class,args);
}
}
application.xml配置文件:
server:
port: 9000
eureka:
instance:
hostname: localhost # 主机名
client:
service-url:
defaultZone: http://localhost:8761/eureka
# eureka服务端地址,将来客户端使用该地址和eureka进行通信
spring:
application:
name: eureka-provider # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径
consumer消费端改动代码:
SpringBoot入口类:
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient //开启动态从Eureka获取地址功能
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class,args);
}
}
application.xml
server:
port: 8000
eureka:
instance:
hostname: localhost # 主机名
client:
service-url:
defaultZone: http://localhost:8761/eureka
# eureka服务端地址,将来客户端使用该地址和eureka进行通信,在服务端配置就是暴露指定端口,客户端就 # 是连接指定端口
spring:
application:
name: eureka-consumer # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径
RestTemplementConfig配置类:
// 作用:在spring的IOC容器中加入RestTemplate对象,实现远程调用
@Configuration
public class RestTemplementConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
controller:
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/goods/{id}")
public Goods findGoodsById(@PathVariable("id") int id){
System.out.println("findGoodsById..."+id);
/*
动态从Eureka Server 中获取 provider 的 ip 和端口
1. 注入 DiscoveryClient 对象.激活
2. 调用方法
*/
//演示discoveryClient 使用
List<ServiceInstance> instances = discoveryClient.getInstances("EUREKA-PROVIDER");
//判断集合是否有数据
if(instances == null || instances.size() == 0){
//集合没有数据
return null;
}
ServiceInstance instance = instances.get(0);
String host = instance.getHost();//获取ip
int port = instance.getPort();//获取端口
System.out.println(host);
System.out.println(port);
String url = "http://"+host+":"+port+"/goods/findOne/"+id;
// 3. 根据从Eureka动态获取的ip地址远程调用方法
Goods goods = restTemplate.getForObject(url, Goods.class);
return goods;
}
}
Eureka控制台效果图:
Eureka – 相关配置及特性
# eureka 一共有4部分 配置
# 1. dashboard:eureka的web控制台配置
# 2. server:eureka的服务端配置
# 3. client:eureka的客户端配置
# 4. instance:eureka的实例配置
instance 属性
客户端配置(服务提供端)
eureka:
instance:
hostname: localhost # 主机名
prefer-ip-address: true # 将当前实例的ip注册到eureka server 中。默认是false 注册主机名
ip-address: 127.0.0.1 # 设置当前实例的ip
instance-id: ${eureka.instance.ip-address}:${spring.application.name}:${server.port} # 设置web控制台显示的 实例id
lease-renewal-interval-in-seconds: 3 # 每隔3 秒发一次心跳包
lease-expiration-duration-in-seconds: 9 # 如果9秒没有发心跳包,服务器呀,你把我干掉吧~
server属性
eureka:
server:
#是否开启自我保护机制,默认true
enable-self-preservation:
#清理间隔(单位毫秒,默认是60*1000)
eviction-interval-timer-in-ms:
client属性
eureka:
client:
service-url:
# eureka服务端地址,将来客户端使用该地址和eureka进行通信
defaultZone:
register-with-eureka: # 是否将自己的路径 注册到eureka上。
fetch-registry: # 是否需要从eureka中抓取数据
dashboard属性
eureka:
dashboard:
enabled: true # 是否启用eureka web控制台
path: / # 设置eureka web控制台默认访问路径
Eureka – 高可用 - 集群的搭建
- 准备两个Eureka Server
- 分别进行配置,相互注册
- Eureka Client 分别注册到这两个 Eureka Server中
搭建两台集群
SpringCloud入口启动类:(两个都一样)
@SpringBootApplication
@EnableEurekaServer // Eureka服务端
public class Eureka01 {
public static void main(String[] args) {
SpringApplication.run(Eureka01.class,args);
}
}
server01—application.yml
注意点:一定要将每台机器的地址写上,包括自己的
server:
port: 8761
eureka:
instance:
hostname: erueka-server01 # 主机名
client:
service-url:
defaultZone: http://erueka-server01:8761/eureka,http://erueka-server01:8762/eureka
spring:
application:
name: erueka-server-ha
server02—application.yml
spring-application-name 属性,集群所有一定要一致
server:
port: 8762
eureka:
instance:
hostname: erueka-server02 # 主机名
client:
service-url:
defaultZone: http://erueka-server01:8761/eureka,http://erueka-server01:8762/eureka
spring:
application:
name: erueka-server-ha
客户端application.yml 配置文件
注意点:一定要将所有服务端的地址都注册上
server:
port: 9000
eureka:
instance:
hostname: provider # 主机名
client:
service-url:
defaultZone: http://erueka-server01:8761/eureka,http://erueka-server02:8762/eureka
spring:
application:
name: eureka-provider # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径
Ribbon组件
概述
- Ribbon是Netflix提供的一个基于HTTP和TCP的客户端负载均衡工具
- Ribbon主要两个功能:
1、简化远程调用
2、负载均衡
负载均衡分为两种:服务端负载均衡,客户端负载均衡
服务端负载均衡:
- 负载均衡算法在服务端
- 由负载均衡器维护维护服务地址列表
客户端负载均衡:
- 负载均衡算法在客户端
- 客户端维护服务地址列表
1、简化远程调用
步骤
1、在声明restTemplate的Bean的时候,添加一个注解 @LoadBalanced
2、在使用restTemplate发起请求时,需要定义url时,host:port可以替换为服务提供方的应用名称
1、在声明restTemplate的Bean的时候,添加一个注解 @LoadBalanced
@Configuration
public class RestTemplementConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
2、在使用restTemplate发起请求时,需要定义url时,host:port可以替换为服务提供方的应用名称
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/goods/{id}")
public Goods findGoodsById(@PathVariable("id") int id){
System.out.println("findGoodsById..."+id);
//远程调用Goods服务中的findOne接口
Goods goods = restTemplate.getForObject("http://EUREKA-PROVIDER/goods/findOne/1", Goods.class);
System.out.println(goods.getName());
return goods;
}
}
2、负载均衡-----消费端
只要你配置了Ribbon默认就有负载均衡的设置-------轮询
设置负载均衡策略
1、编码
@Configguration
public class MyRule{
@Bean
public IRule rule(){
// 设置负载均衡策略 为 随机,需要什么规则就返回IRule对应的实现类
return new RandomRule();
}
}
配置Ribbon的负载均衡策略:
name:设置 服务提供的应用名称-----有多个服务,可能不同的服务负载均衡策略不同,需要指定服务
configuration:设置负载均衡Bean
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient //开启动态从Eureka获取地址功能
@RibbonClient(name="EUREKA-PROVIDER",configuration=MyRule.class)
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class,args);
}
}
2、配置
在消费端的application.yml的配置文件中
# 配置的方式设置 Ribbon的负载均衡策略
EUREKA-PROVIDER: # 设置服务提供方的应用名称
ribbon:
NFloadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 策略类
–有多个服务,可能不同的服务负载均衡策略不同,需要指定服务
configuration:设置负载均衡Bean
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient //开启动态从Eureka获取地址功能
@RibbonClient(name="EUREKA-PROVIDER",configuration=MyRule.class)
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class,args);
}
}
2、配置
在消费端的application.yml的配置文件中
# 配置的方式设置 Ribbon的负载均衡策略
EUREKA-PROVIDER: # 设置服务提供方的应用名称
ribbon:
NFloadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 策略类