配置中心(config), 熔断器(hystrix),(负载均衡)ribbon
GitHub代码地址
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-config-server
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: [email protected] #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
org.springframework.boot
spring-boot-starter-test
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-config
配置文件(注意要使用配置中心加载配置,配置文件名为 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主要是做负载均衡,要做负载均衡就要有多个服务提供者,在消费者调用时进行负载均衡。
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:
启动测试
两个服务提供者就准备好了
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
启动类:
@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();
}
}
org.springframework.boot
spring-boot-starter-test
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
配置
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";
}
}
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-openfeign
配置
server:
port: 9004
eureka:
client:
registerWithEureka: false #不注册到Eureka,不在注册中心显示
service-url:
defaultZone: http://127.0.0.1:7001/eureka
feign:
hystrix:
enabled: true #开启熔断支持
//添加一个后备工厂,在失败时使用
@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 {
@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;
}
}