SpringCloud-Dalston版本学习
参考文章:https://blog.didispace.com/spring-cloud-learning/
一、服务注册与发现(Eureka、Consul)
1.Spring Cloud简介
-
Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等操作提供了一种简单的开发方式。
-
Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品),比如:Spring Cloud Config、Spring Cloud Netflix、Spring Cloud0 CloudFoundry、Spring Cloud AWS、Spring Cloud Security、Spring Cloud Commons、Spring Cloud Zookeeper、Spring Cloud CLI等项目。
2.微服务架构
- 简单的说,微服务架构就是将一个完整的应用从数据存储开始垂直拆分成多个不同的服务,每个服务都能独立部署、独立维护、独立扩展,服务与服务间通过诸如RESTful API的方式互相调用。
3.创建“服务注册中心”(服务端)
eureka-server
①使用Idea创建Eureka服务端
②查看依赖,SpringBoot的pom.xml里新增的依赖
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.0</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<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>
③配置application.properties
spring.application.name=eureka-server
server.port=1001
eureka.instance.hostname=localhost
#声明是否将自己的信息注册到 Eureka 服务器上
eureka.client.register-with-eureka=false
#是否到 Eureka 服务器中抓取注册信息
eureka.client.fetch-registry=false
④启动类添加@EnableEurekaServer注解
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
⑤启动,访问:http://localhost:1001/,完成服务端
4.创建“服务提供方”(客户端)
eureka-client
①使用Idea创建Eureka客户端
②查看依赖,SpringBoot的pom.xml里新增的依赖
③配置application.properties
spring.application.name=eureka-client
server.port=2001
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
spring.application.name
属性,我们可以指定微服务的名称后续在调用的时候只需要使用该名称就可以进行服务的访问。eureka.client.serviceUrl.defaultZone
属性对应服务注册中心的配置内容,指定服务注册中心的位置。
当使用postman访问http://localhost:1001/eureka/时
④启动类添加@EnableEurekaClient注解
@EnableEurekaClient
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
创建一个接口
@RestController
public class DcController {
@Autowired
DiscoveryClient discoveryClient;
@GetMapping("/dc")
public String dc() {
String services = "Services: " + discoveryClient.getServices() ;
System.out.println(services);
return services;
}
}
DiscoveryClient
是Spring Cloud对服务治理做的一层抽象
⑤单独启动客户端
出现错误:原因没有启动服务端
http://localhost:2001/dc并且不能输出discoveryClient.getServices()
⑥正确操作,先启动服务端,再启动客户端
二、服务消费(基础)
1.使用LoadBalancerClient
从LoadBalancerClient
接口的命名中,我们就知道这是一个负载均衡客户端的抽象定义,下面我们就看看如何使用Spring Cloud提供的负载均衡器客户端接口来实现服务的消费。
2.创建一个消费者工程
eureka-consumer
①添加依赖(省略了部分依赖)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
②配置application.properties
,指定eureka注册中心的地址
spring.application.name=eureka-consumer
server.port=2101
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
③修改启动类。@EnableDiscoveryClient
注解用来将当前应用加入到服务治理体系中。
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaApplication {
@Bean
// @LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
注入了LoadBalancerClient
和RestTemplate
,并在/consumer
接口的实现中,先通过loadBalancerClient
的choose
函数来负载均衡的选出一个eureka-client
的服务实例,这个服务实例的基本信息存储在ServiceInstance
中,然后通过这些对象中的信息拼接出访问/dc
接口的详细地址,最后再利用RestTemplate
对象实现对服务提供者接口的调用。
④创建一个接口用来消费eureka-client提供的接口:
@RestController
public class DcController {
@Autowired
LoadBalancerClient loadBalancerClient;
@Autowired
RestTemplate restTemplate;
@GetMapping("/consumer")
public String dc() {
ServiceInstance serviceInstance = loadBalancerClient.choose("eureka-client");
String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/dc";
System.out.println(url);
return restTemplate.getForObject(url, String.class);
}
}
⑤启动,先启动eureka-server,eureka-client,eureka-consumer
eureka-serverhttp://localhost:1001/存在两个注册信息
eureka-clienthttp://localhost:2001/dc
eureka-consumerhttp://localhost:2101/consumer
三、服务消费(Ribbon)
1.Spring Cloud Ribbon
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。它是一个基于HTTP和TCP的客户端负载均衡器。它可以通过在客户端中配置ribbonServerList来设置服务端列表去轮询访问以达到均衡负载的作用。
当Ribbon与Eureka联合使用时,ribbonServerList会被DiscoveryEnabledNIWSServerList重写,扩展成从Eureka注册中心中获取服务实例列表。同时它也会用NIWSDiscoveryPing来取代IPing,它将职责委托给Eureka来确定服务端是否已经启动。
2.创建一个消费者工程
eureka-consumer-ribbon
①SpringBoot旧版中需要导入这两条依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-client</artifactId>
</dependency>
-
SpringBoot2.x版本只需要导入这一条
-
下面依赖已经整合了ribbon包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
②配置application.properties
,指定eureka注册中心的地址
spring.application.name=eureka-consumer
server.port=2101
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
③修改应用主类。为RestTemplate
增加@LoadBalanced
注解:
@EnableDiscoveryClient
@SpringBootApplication
public class RibbonApplication {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
}
④修改Controller。去掉原来通过LoadBalancerClient
选取实例和拼接URL的步骤,直接通过RestTemplate发起请求。
@RestController
public class DcController {
@Autowired
RestTemplate restTemplate;
@GetMapping("/consumer")
public String dc() {
return restTemplate.getForObject("http://eureka-client/dc", String.class);
}
}
⑤启动,先启动eureka-server,eureka-client,eureka-consumer-ribbon
eureka-consumer-ribbonhttp://localhost:2101/consumer
去掉了原来与LoadBalancerClient
相关的逻辑之外,对于RestTemplate
的使用,我们的第一个url参数有一些特别。这里请求的host位置并没有使用一个具体的IP地址和端口的形式,而是采用了服务名的方式组成。那么这样的请求为什么可以调用成功呢?因为Spring Cloud Ribbon有一个拦截器,它能够在这里进行实际调用的时候,自动的去选取服务实例,并将实际要请求的IP地址和端口替换这里的服务名,从而完成服务接口的调用。
四、服务消费(Feign)
1.Spring Cloud Feign
Spring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端。它使得编写Web服务客户端变得更加简单。我们只需要通过创建接口并用注解来配置它既可完成对Web服务接口的绑定。它具备可插拔的注解支持,包括Feign注解、JAX-RS注解。它也支持可插拔的编码器和解码器。Spring Cloud Feign还扩展了对Spring MVC注解的支持,同时还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。
2.创建一个消费者工程
eureka-consumer-feign
①添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
我的SpringBoot2.x导入此依赖报错
可采用这两种方式
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
或者
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
文章地址:https://www.cnblogs.com/xiaozhengtongxue/p/13549152.html
②配置application.properties
,指定eureka注册中心的地址
spring.application.name=eureka-consumer
server.port=2101
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
③创建一个Feign的客户端接口定义。使用@FeignClient
注解来指定这个接口所要调用的服务名称,接口中定义的各个函数使用Spring MVC的注解就可以来绑定服务提供方的REST接口,比如下面就是绑定eureka-client
服务的/dc
接口的例子:
@FeignClient("eureka-client")
public interface DcClient {
@GetMapping("/dc")
String consumer();
}
④修改Controller。通过定义的feign客户端来调用服务提供方的接口:
@RestController
public class DcController {
@Autowired
DcClient dcClient;
@GetMapping("/consumer")
public String dc() {
return dcClient.consumer();
}
}
通过Spring Cloud Feign来实现服务调用的方式更加简单了,通过@FeignClient
定义的接口来统一的生命我们需要依赖的微服务接口。而在具体使用的时候就跟调用本地方法一点的进行调用即可。由于Feign是基于Ribbon实现的,所以它自带了客户端负载均衡功能,也可以通过Ribbon的IRule进行策略扩展。另外,Feign还整合的Hystrix来实现服务的容错保护,在Dalston版本中,Feign的Hystrix默认是关闭的。
⑤启动,先启动eureka-server,eureka-client,eureka-consumer-feign
eureka-consumer-feignhttp://localhost:2101/consumer
五、Spring Cloud Feign的文件上传实现
看不懂跳过
六、分布式配置中心
Spring Cloud Config是Spring Cloud团队创建的一个全新项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端与客户端两个部分。其中服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密/解密信息等访问接口;而客户端则是微服务架构中的各个微服务应用或基础设施,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。Spring Cloud Config实现了对服务端和客户端中环境变量和属性配置的抽象映射,所以它除了适用于Spring构建的应用程序之外,也可以在任何其他语言运行的应用程序中使用。由于Spring Cloud Config实现的配置中心默认采用Git来存储配置信息,所以使用Spring Cloud Config构建的配置服务器,天然就支持对微服务应用配置信息的版本管理,并且可以通过Git客户端工具来方便的管理和访问配置内容。当然它也提供了对其他存储方式的支持,比如:SVN仓库、本地化文件系统。
1.准备配置仓库
在github里面新建一个仓库,并添加一下两个文件。
- 在git仓库中该项目的默认配置文件。config-client.yml
info:
profile: default
- 为了演示加载不同环境的配置,我们可以在git仓库中再创建一个针对dev环境的配置文件
config-client-dev.yml
info:
profile: dev
2.构建配置中心
①创建一个SpringBoot工程,命名为config-server-git
可以看到新增加的依赖
②添加@EnableConfigServer
注解,开启Spring Cloud Config的服务端功能。
@EnableConfigServer
@SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
③在application.yml
中添加配置服务的基本信息以及Git仓库的相关信息
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://github.com/yezhinao/SpringCloudDemo.git
# search-paths: repo
# username:
# password:
server:
port: 1201
- spring.application.name:对应配置文件规则中的
{application}
部分 - spring.cloud.config.profile:对应配置文件规则中的
{profile}
部分 - spring.cloud.config.label:对应配置文件规则中的
{label}
部分 - spring.cloud.config.uri:配置中心仓库或者是
config-server
的地址(这里是仓库地址)
请求配置中心的方式
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
- http://localhost:8888/abc-config-server/dev #不显示配置默认label的话,默认获取master分支上的abc-config-server-dev.yml
- http://localhost:8888/abc-config-server/dev/develop #获取develop分支上的abc-config-server-dev.yml资源
⑤通过Postman进行访问,
推荐写法1:/{application}/{profile}[/{label}]
http://localhost:1201/config-client/dev/main
-
应用名:config-client,环境名:dev,分支名:master,以及default环境和dev环境的配置内容。
-
返回结果的name,profiles,label返回结果是url上面的信息。
-
此外,label必须是main值才能访问到,因为我的文件使用main分支创建的
推荐写法2:http://localhost:1201/main/config-client-dev.yml
/{label}/{application}-{profile}.yml
3.构建客户端
①创建一个SpringBoot工程,命名为config-client
②导入依赖
我遇到bootstrap.yml无法加载的问题
推荐使用依赖文件如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<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>
③启动类添加@EnableDiscoveryClient
注解。
@EnableDiscoveryClient
@SpringBootApplication
public class GitcApplication {
public static void main(String[] args) {
SpringApplication.run(GitcApplication.class, args);
}
}
④新建bootstrap.yml配置,删除application.properties配置
spring:
application:
name: config-client
cloud:
config:
uri: http://localhost:1201/
#如果profile是控制一定要写一个default
profile: default
label: main
server:
port: 2001
相当于http://localhost:1201/config-client/default/main
⑤启动config-client
出现这一条已经成功了一半
2021-01-13 15:28:13.799 INFO 34192 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://localhost:1201/
2021-01-13 15:28:15.943 INFO 34192 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Located environment: name=config-client, profiles=[default], label=main, version=e925dd243f95baddea75d9fb7e804c913adc81c5, state=null
2021-01-13 15:28:15.944 INFO 34192 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-configClient'}, BootstrapPropertySource {name='bootstrapProperties-https://github.com/yezhinao/SpringCloudDemo/config-client.yml'}]
⑥创建访问接口
@RestController
@RefreshScope
public class ConfigClientController {
@Value("${info.profile}")
private String infoProfile;
@RequestMapping("/infoProfile")
public String getInfoProfile(){
return infoProfile;
}
}
最后访问http://localhost:2001/infoProfile
断更。。。。。。
有一说一,零基础的小白,dd的springcloud文章成功劝退我,换个学习资料,回头再继续。