SpringCloud简介
Spring Cloud 为开发者提供了工具来快速构建分布式系统中的一些常见模式(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话,集群状态)。分布式系统的协调导致了样板模式,使用 Spring Cloud 开发人员可以快速建立实现这些模式的服务和应用程序。
SpringCloud是基于SpringBoot的,所以在在选取SpringCloud版本时需要注意一下,这是目前官网上SpringCloud对应到SpringBoot的版本:
SpringCloud的版本是以大写字母来命名的,字母越大表示版本越新,目前Spring Cloud Dalston, Edgware, Finchley, and Greenwich have all reached end of life status and are no longer supported.
具体参考官网介绍:
https://spring.io/projects/spring-cloud
创建服务注册与发现工程
父工程创建
创建一个maven父工程,引入pom依赖,父工程的依赖如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.9.RELEASE</version>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring.cloud-version>Hoxton.SR12</spring.cloud-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>
</dependencies>
</dependencyManagement>
这里使用的是2.3.9.RELEASE版本的springboot以及Hoxton.SR12版本的springcloud,这里的SRX指的是优化后的第多少个版本。父工程创建好后,其它子模块继承该pom。
Eureka注册中心创建
pom依赖引入
在父工程下新建一个子模块springacloud-eureka-server,引入pom依赖,一定要引入这个web依赖,否则应用会启动不了
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
启动类
启动一个注册中心,只需要一个注解@EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class);
}
}
配置文件
创建application.properties
spring.application.name=eureka-server
server.port=8090
eureka.instance.hostname=localhost
# 自己为注册中心不需要注册
eureka.client.register-with-eureka=false
# 自己为注册中心不需要拉取注册信息
eureka.client.fetch-registry=false
eureka.client.healthcheck.enabled=true
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
启动工程
eureka server 是有界面的,启动工程,打开浏览器访问: http://localhost:8090/ ,界面如下
服务提供者创建
当client向server注册时,它会提供一些元数据,例如主机和端口,URL,主页等。Eureka server 从每个client实例接收心跳消息。 如果心跳超时,则通常将该实例从注册server中删除。
pom依赖引入
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
启动类
通过注解@EnableEurekaClient 表明自己是一个eurekaclient.
@SpringBootApplication
@EnableEurekaClient
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class,args);
}
}
创建服务提供者
@RestController
public class HelloController {
@Value("${server.port}")
private String port;
@RequestMapping("/")
public String home() {
return "Hello world "+port;
}
}
配置文件
创建application.properties,添加注册中心的地址,需要指明spring.application.name,这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name 。 启动工程,打开http://localhost:8761 ,即eureka server 的网址:
spring.application.name=eureka-client01
server.port=8091
eureka.client.serviceUrl.defaultZone=http://localhost:8090/eureka/
启动完成后打开Eureka注册中心,发现eureka-client01已经注册成功
访问地址http://localhost:8091/,可以在页面看到
Hello world 8091
服务消费者创建(Ribbon)
基于上面创建的服务提供者再创建第二个服务提供者,方便后续进行测试。在这个新的服务提供者中只需要修改一下配置文件中的端口号为8092即可启动工程,这时在注册中心可以看到两个服务提供者
确定好服务提供者之后,接下来开始创建服务消费方,需要新建一个模块springcloud-ribbon
pom依赖引入
需要引入一个新的依赖spring-cloud-starter-netflix-ribbon
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
启动类
通过Ribbon做为负载均衡的客户端
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
创建服务消费者
写了一个测试类HelloRibbonService,通过之前注入的RestTemplate来消费EUREKA-CLIENT01服务的接口,在ribbon中它会根据服务名来选择具体的服务实例,根据服务实例在请求的时候会用具体的url替换掉服务名
@RestController
public class HelloRibbonController {
@Autowired
HelloRibbonService helloRibbonService;
@GetMapping(value = "/hi")
public String hi(@RequestParam String name) {
return helloRibbonService.hiService( name );
}
}
@Service
public class HelloRibbonService {
@Autowired
RestTemplate restTemplate;
public String hiService(String name) {
return restTemplate.getForObject("http://EUREKA-CLIENT01/",String.class);
}
}
配置文件
spring.application.name=service-ribbon
server.port=8093
eureka.client.serviceUrl.defaultZone=http://localhost:8090/eureka/
启动该模块后,在浏览器上多次访问http://localhost:8093/hi/?name=handerh会出现:
Hello world 8091
Hello world 8092
服务消费者创建(Feign)
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。
新建一个模块springcloud-openfeign,在它的pom文件引入Feign的起步依赖spring-cloud-starter-feign
pom依赖引入
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
启动类
在程序的启动类OpenFeignApplication,加上@EnableFeignClients注解开启Feign的功能:
@SpringBootApplication
@EnableFeignClients
public class OpenFeignApplication {
public static void main(String[] args) {
SpringApplication.run(OpenFeignApplication.class, args);
}
}
创建服务消费者
定义一个feign接口,通过@ FeignClient(“服务名”),来指定调用哪个服务。比如在代码中调用了EUREKA-CLIENT01服务的“/”接口,代码如下:
@FeignClient(value = "EUREKA-CLIENT01",fallback = HelloOpeServiceImpl.class)
public interface HelloOpeService {
@RequestMapping(value = "/",method = RequestMethod.GET)
String sayHiFromClientOne(@RequestParam(value = "name") String name);
}
@RestController
public class HelloOpenController {
@Autowired
HelloOpeService helloOpeService;
@GetMapping(value = "/hi")
public String sayHi(@RequestParam String name) {
return helloOpeService.sayHiFromClientOne( name );
}
}
配置文件
spring.application.name=service-openfeign
server.port=8094
eureka.client.serviceUrl.defaultZone=http://localhost:8090/eureka/
启动该模块后,在浏览器上多次访问http://localhost:8094/hi/?name=handerh会出现:
Hello world 8091
Hello world 8092