整理一下:
-
@EnableEurekaServer 注册中心
-
@EnableDiscoveryClient 提供服务
-
@EnableFeignClients 消费者(Feign特有的,而且他自带断路器)
-
@EnableHystrix 断路器
-
@EnableHystrixDashboard 开启仪表盘
-
@EnableZuulProxy 开启路由
事先声明,一定要按照我上面的pom写,因为各种版本冲突,哎。真是操蛋 。没必要追求最新的。刚开始能跑起来就行。不多说,看代码,如果有错误,看我另外一篇,。
新建一个服务中心:目的是让你的写的服务都注册上面,然后还需要写几个服务,然后还要写几个消费者
----------------------------------------------注册中心------------------------------------------------
erueka pom.xml
4.0.0 com.example eureka 0.0.1-SNAPSHOT jar eureka Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 1.5.1.RELEASE UTF-8 UTF-8 1.8 Camden.SR6 5.1.30 org.springframework.cloud spring-cloud-starter-eureka-server org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.boot spring-boot-maven-plugin
EurekaApplication.java 启动类
package com.example.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication@EnableEurekaServerpublic class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); }}
application.yml
server: port: 9999spring: application: name: eureka-service # eureka server 相关配置eureka: instance: hostname: localhost client: registerWithEureka: false #表示是否将自己注册到Eureka Server上,默认为true fetchRegistry: false #表示是否从Eureka Server上获取注册信息,默认为true serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka #设置服务注册中心的URL
ok,一个最简单的注册中心就好了
----------------------------------------------注册服务------------------------------------------------
pom.xml
4.0.0 com.example eurekaclient 0.0.1-SNAPSHOT jar eureka-client Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 1.5.1.RELEASE UTF-8 UTF-8 1.8 Camden.SR6 org.springframework.cloud spring-cloud-starter-eureka org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.boot spring-boot-maven-plugin
EurekaClientApplication.java
package com.example.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication@EnableDiscoveryClientpublic class EurekaClientApplication { public static void main(String[] args) { SpringApplication.run(EurekaClientApplication.class, args); }}
application.yml
server: port: 9998spring: application: name: eureka-clienteureka: client: serviceUrl: defaultZone: http://localhost:9999/eureka
----------------------------------------------负载均衡ribbon----------------------------------------
将注册服务再复制一份,端口改一下,spring.application.name.eureka-client 这个要一样 这样就配了一个小集群。然后用ribbon来创建消费者,配置一个简单的负载均衡服务
pom.xml
4.0.0 com.example springcloudribbon 0.0.1-SNAPSHOT jar springcloud-ribbon Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 1.5.1.RELEASE UTF-8 UTF-8 1.8 Camden.SR6 org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-eureka org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-starter-ribbon org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.boot spring-boot-maven-plugin spring-milestones Spring Milestones https://repo.spring.io/milestone false
SpringcloudRibbonApplication.java
package com.example.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.web.client.RestTemplate;@SpringBootApplication@EnableDiscoveryClientpublic class SpringcloudRibbonApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudRibbonApplication.class, args); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); }}
HelloControler.java
package com.example.demo;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;/** * Created by lilipo on 2018/5/3. */@RestControllerpublic class HelloControler { @Autowired HelloService helloService; @RequestMapping(value = "/hi") public String hi(@RequestParam String name){ return helloService.hiService(name); }}
HelloService.java
package com.example.demo;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.web.client.RestTemplate;/** * Created by lilipo on 2018/5/3. */@Servicepublic class HelloService { @Autowired RestTemplate restTemplate; public String hiService(String name) { return restTemplate.getForObject("http://eureka-client/hi?name="+name,String.class); }}
如果正确启动的话,你会在浏览器上看到端口轮询出现。就说明负载均衡配置好了。实在是太简单了。参考博客:
----------------------------------------------服务消费者(Feign)----------------------------------------
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。
简而言之:
- Feign 采用的是基于接口的注解
- Feign 整合了ribbon
pom.xml
4.0.0 com.example springcloudfeign 0.0.1-SNAPSHOT jar springcloud-feign Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 1.5.1.RELEASE UTF-8 UTF-8 1.8 Camden.SR6 5.1.30 org.springframework.cloud spring-cloud-starter-eureka org.springframework.cloud spring-cloud-starter-feign org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.boot spring-boot-maven-plugin
SpringcloudFeignApplication.java (@EnableFeignClients注解开启Feign的功能)
package com.example.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.feign.EnableFeignClients;@SpringBootApplication@EnableDiscoveryClient@EnableFeignClientspublic class SpringcloudFeignApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudFeignApplication.class, args); }}
HiController.java
package com.example.demo;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;/** * Created by lilipo on 2018/5/3. */@RestControllerpublic class HiController { @Autowired SchedualServiceHi schedualServiceHi; @RequestMapping(value = "/hi",method = RequestMethod.GET) public String sayHi(@RequestParam String name){ return schedualServiceHi.sayHiFromClientOne(name); }}
SchedualServiceHi.java (定义一个feign接口,通过@ FeignClient(“服务名”),来指定调用哪个服务。比如在代码中调用了service-hi服务的“/hi”接口)
package com.example.demo;import org.springframework.cloud.netflix.feign.FeignClient;import org.springframework.stereotype.Service;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;/** * Created by lilipo on 2018/5/3. */@FeignClient(value = "eureka-client")@Servicepublic interface SchedualServiceHi { @RequestMapping(value = "/hi",method = RequestMethod.GET) String sayHiFromClientOne(@RequestParam(value = "name") String name);}
如果正确启动,那么会实现和ribbon一样的效果。默认有负载均衡的作用,更加简单。
参考博客:
----------------------------------------------断路器(Hystrix)----------------------------------------
断路器(Hystrix)的作用就是当你的调用服务的时候,注册的服务挂了,这时候会走一个你指定的方法,而不是一直等待或者报错。分别从ribbon和Feign两种情况做演示
只是改造而已,在ribbon的项目上增加下面这个依赖
org.springframework.cloud spring-cloud-starter-hystrix
在启动类上增加@EnableHystrix注解
改造HelloService类,在hiService方法上加上@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法,熔断方法直接返回了一个字符串,字符串为”hi,”+name+”,sorry,error!”,代码如下:
@Servicepublic class HelloService { @Autowired RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "hiError") public String hiService(String name) { return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class); } public String hiError(String name) { return "hi,"+name+",sorry,error!"; }}
当 service-hi 工程不可用的时候,service-ribbon调用 service-hi的API接口时,会执行快速失败,直接返回一组字符串,而不是等待响应超时,这很好的控制了容器的线程阻塞。
Feign中使用断路器
Feign是自带断路器的,在D版本的Spring Cloud中,它没有默认打开。需要在配置文件中配置打开它,在配置文件加以下
feign.hystrix.enabled=true
基于service-feign工程进行改造,只需要在FeignClient的SchedualServiceHi接口的注解中加上fallback的指定类就行了:
@FeignClient(value = "service-hi",fallback = SchedualServiceHiHystric.class)public interface SchedualServiceHi { @RequestMapping(value = "/hi",method = RequestMethod.GET) String sayHiFromClientOne(@RequestParam(value = "name") String name);}
SchedualServiceHiHystric需要实现SchedualServiceHi 接口,并注入到Ioc容器中,代码如下:
@Componentpublic class SchedualServiceHiHystric implements SchedualServiceHi { @Override public String sayHiFromClientOne(String name) { return "sorry "+name; }}
------------------------Hystrix Dashboard (断路器:Hystrix 仪表盘)-------------------------------------
基于service-ribbon 改造
在pom中增加依赖
org.springframework.boot spring-boot-starter-actuator org.springframework.cloud spring-cloud-starter-hystrix-dashboard org.springframework.cloud spring-cloud-starter-hystrix
在主程序启动类中加入@EnableHystrixDashboard注解,开启hystrixDashboard:
ok,访问:http://192.168.1.28:9996/hystrix 端口号是你这个ribbon项目的端口号 会出现一个熊猫界面
第一个框填上http://localhost:9996/hystrix.stream 第二个Title 随便填。自定义名字 然后点击下面的按钮会出现另外一个界面
基于service-ribbon 改造 (和ribbon的差不多,但是有坑,依赖问题,需要注意一下。 )
添加依赖
org.springframework.boot spring-boot-starter-actuator 1.5.10.RELEASE org.springframework.cloud spring-cloud-starter-hystrix-dashboard RELEASE
在主程序启动类中加入@EnableHystrixDashboard注解,开启hystrixDashboard:
参考博客:
------------------------------------------路由网关(zuul)-----------------------------------------------
新建一个zuul网关项目
pom.xml
4.0.0 com.example springcloudzuul 0.0.1-SNAPSHOT jar springcloud-zuul Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 1.5.1.RELEASE UTF-8 UTF-8 1.8 Camden.SR6 5.1.30 org.springframework.cloud spring-cloud-starter-eureka org.springframework.cloud spring-cloud-starter-zuul org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.boot spring-boot-maven-plugin
SpringcloudZuulApplication.java(@EnableZuulProxy注解开启路由)
package com.example.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.netflix.zuul.EnableZuulProxy;@EnableZuulProxy@EnableEurekaClient@SpringBootApplicationpublic class SpringcloudZuulApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudZuulApplication.class, args); }}
application.yml
eureka: client: serviceUrl: defaultZone: http://localhost:9999/eureka/server: port: 9994spring: application: name: service-zuulzuul: routes: api-a: path: /api-a/** serviceId: service-ribbon api-b: path: /api-b/** serviceId: service-feign
首先指定服务注册中心的地址为,服务的端口为9994,服务名为service-zuul;以/api-a/ 开头的请求都转发给service-ribbon服务;以/api-b/开头的请求都转发给service-feign服务;
访问: 和 看结果 参考博客: