详解搭建spring cloud的实例Demo,跟着一步一步走,肯定可以的
直接跟上上一章 继续搭建
配置中心(config), 熔断器(hystrix),(负载均衡)ribbon
GitHub代码地址
配置中心(config)
- 1.在父目录下创建子项目,方式和上一章一致(普通maven项目)
- 2.导入所需依赖
<dependencies>
<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>
</dependency>
<!--Eureka的客户端的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--配置中心依赖支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
- 3.配置
server:
port: 1299
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:7001/eureka
instance:
prefer-ip-address: true
spring:
application:
name: CONFIG-SERVER
cloud:
config:
server:
git:
uri: https://github.com/wl1006/test.git #git文件地址
username: 1006wanglong@gmail.com #Github账号
password: xxxxxxxx #GitHub账号密码
GitHub文件预览,如要实践,则需在GitHub上创建一个仓库
文件内容
spring:
profiles:
active:
- dev
---
server:
port: 3355
spring:
application:
name: MICRO-SERVER-DEV
profiles: dev #开发环境
---
server:
port: 3356
spring:
application:
name: MICRO-SERVER-TEST
profiles: test #测试环境
- 创建启动类
@SpringBootApplication
@EnableEurekaClient
@EnableConfigServer //启动配置中心服务
public class Application_Config {
public static void main(String[] args) {
SpringApplication.run(Application_Config.class);
}
}
-
启动测试,是否能拿到配置
测试地址(ip根据配置):
http://127.0.0.1:1299/application/dev
http://127.0.0.1:1299/application/test -
测试结果(因为我安装了json格式化插件,原为json字符串)
-
其他项目从配置中心获取配置
为保持原结构,重新建一个项目进行测试
配置pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Eureka客户端依赖-->
<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-config</artifactId>
</dependency>
</dependencies>
配置文件(注意要使用配置中心加载配置,配置文件名为 bootstrap.yml)
spring:
cloud:
config:
uri: http://127.0.0.1:1299 #配置服务器
label: master #分支
name: application #github上面名称
profile: dev #环境
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:7001/eureka #告诉服务提供者要把服务注册到哪儿
instance:
prefer-ip-address: true #显示客户端真实ip
启动类
@SpringBootApplication
@EnableEurekaClient
public class Application_Config_Provider {
public static void main(String[] args){
SpringApplication.run(Application_Config_Provider.class);
}
}
服务提供
@RestController
@RequestMapping("/config")
public class HelloController {
@GetMapping("/hello")
public String index() {
return "我是一个数据!";
}
}
启动项目,因为配置文件中选择的是dev环境,所有端口和服务名称则为
端口:3355
服务名:MICRO-SERVER-DEV
将服务添加到网关,网关配置
server:
port: 9527
spring:
application:
name: ZUUL-SERVER
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:7001/eureka
zuul:
routes:
provider.serviceId: TEST-PROVIDER
provider.path: /test/** #匹配指定的路径,资源匹配的路径才会拦截,转发
configProvider.serviceId: MICRO-SERVER-DEV #新增
configProvider.path: /config-provide/** #新增
ignored-services: "*" #忽略直接使用服务名访问 *忽略所有的
prefix: /server #统一给访问前缀
至此,配置中心就基本配置完毕,测试的项目和上一个服务提供者效果一致,只是配置的获取方式是从配置中心获取
ribbon
ribbon主要是做负载均衡,要做负载均衡就要有多个服务提供者,在消费者调用时进行负载均衡。
- 创建第二个服务提供者
配置依赖和原来提供者一致(拷贝server-provider依赖,controller,配置文件)
唯一修改(配置文件application.yml中的端口更改,其他不要改)
server:
port: 8002 #更改
spring:
application:
name: TEST-PROVIDER
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:7001/eureka #注册到Eureka的地址
项目结构
在server-provider2的服务提供中修改一下数据,方便测试区分
server-provider的controller:
server-provider2的controller:
启动测试
两个服务提供者就准备好了
- 创建一个消费者进行负载均衡调用
添加依赖:
<dependencies>
<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>
</dependency>
<!--eureka客户端,服务消费者也要从注册中心获取可用服务列表-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
启动类:
@SpringBootApplication
@EnableEurekaClient
public class Application_Ribbon {
public static void main(String[] args) {
SpringApplication.run(Application_Ribbon.class);
}
@Bean
@LoadBalanced //开启负载均衡的功能
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
controller(注意URL,ip端口换为服务名称)
@RestController
@RequestMapping("consumer")
public class ConsumerRibbonController {
@Autowired
private RestTemplate restTemplate;
private final String URL = "http://TEST-PROVIDER/provider/get";
@GetMapping("get")
public String get() {
String data = restTemplate.getForObject(URL, String.class);
return data;
}
}
配置文件
server:
port: 9003
eureka:
client:
registerWithEureka: false #不注册到Eureka,不在注册中心显示
service-url:
defaultZone: http://127.0.0.1:7001/eureka
测试(轮询策略):
更改负载均衡策略
@SpringBootApplication
@EnableEurekaClient
public class Application_Ribbon {
public static void main(String[] args) {
SpringApplication.run(Application_Ribbon.class);
}
@Bean
@LoadBalanced //开启负载均衡的功能
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
//修改默认的负载均衡策略
@Bean
public IRule myRule() {
//随机策略
return new RandomRule();
}
}
测试(随机策略)
熔断器(hystrix)
- 创建一个服务器提供者,模拟业务服务
依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Eureka客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
配置
server:
port: 8004
spring:
application:
name: TEST-HYSTRIX-PROVIDER #服务名称
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:7001/eureka #注册到Eureka的地址
启动类
@SpringBootApplication
@EnableEurekaClient
public class Application_Hystrix_Provider {
public static void main(String[] args) {
SpringApplication.run(Application_Hystrix_Provider.class);
}
}
controller(模拟业务,如果num等于123,则判定为失败)
@RestController
@RequestMapping("provider")
public class HystrixProviderController {
@GetMapping("get/{num}")
public String get(@PathVariable("num") Integer num) {
if (num == 123) {
throw new RuntimeException("FAILED");
}
return num + "==SUCCEED";
}
}
测试
- 创建一个基于fegin的消费者
依赖
<dependencies>
<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>
</dependency>
<!--Eureka的客户端的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--Feign的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
配置
server:
port: 9004
eureka:
client:
registerWithEureka: false #不注册到Eureka,不在注册中心显示
service-url:
defaultZone: http://127.0.0.1:7001/eureka
feign:
hystrix:
enabled: true #开启熔断支持
基本结构
fegin接口
//添加一个后备工厂,在失败时使用
@FeignClient(value = "TEST-HYSTRIX-PROVIDER", fallbackFactory = ProviderClientFactory.class)
@RequestMapping("provider")
public interface ProviderClient {
@GetMapping("get/{num}")
public String get(@PathVariable("num") String num);
}
后备工厂
@Component
public class ProviderClientFactory implements FallbackFactory<ProviderClient> {
@Override
public ProviderClient create(Throwable cause) {
return new ProviderClient() {
@Override
public String get(String num) {
return "Feign调用失败";
}
};
}
}
启动类
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = "com.wlg.hystrix.service")
public class Application_Hystrix_Consumer {
public static void main(String[] args) {
SpringApplication.run(Application_Hystrix_Consumer.class);
}
}
controller
@RestController
@RequestMapping("consumer")
public class HystrixConsumerController {
@Autowired
private ProviderClient providerClient;
@GetMapping("get/{num}")
public String get(@PathVariable("num") String num) {
String data = providerClient.get(num);
return data;
}
}
测试
hystrix就会在调用服务失败时,进行熔断,返回托底数据,避免了请求阻塞!