本文共 8912 字,大约阅读时间需要 29 分钟。
最近几年,微服务很火爆,随着公司规模的上升,对应各种服务也在不断的完善和增加,软件的架构从之前的单体架构逐渐朝着功能分解成不同模块继而拆分成一组特定服务。
著名的扩展立方体如上图所示,
X轴通过部署多个相同实例,继而在多个实例之间进行负载均衡;Z轴根据请求中特殊属性对请求进行路由;Y轴扩展根据功能将应用拆分为服务。
微服务将一个复杂的单体系统分解成若干小的业务,服务的边界明确,服务之间耦合降低,服务分布式集群化部署,可实现负载聚恒和熔断。
spring cloud中,eureka
实现了服务注册和发现 ribbon
实现了服务的负载均衡 hystrix
实现了服务熔断机制 zuul
实现了服务路由网关 下面分别进行示例入门 首先搭建eureka-server,进行服务的注册,
pom依赖如下:spring-cloud-test-001 com.leo.test 1.0.0-snapshot 4.0.0 eureka-server-001 org.springframework.cloud spring-cloud-starter-netflix-eureka-server org.springframework.boot spring-boot-maven-plugin
querka-server配置application.yml如下:
---server: port: 8081eureka: instance: prefer-ip-address: true hostname: leo-node client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://${eureka.instance.hostname}:8082/eurekaspring: profiles: test-001-1---server: port: 8082eureka: instance: prefer-ip-address: true hostname: leo-node client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://${eureka.instance.hostname}:8081/eurekaspring: profiles: test-001-2
编写启动类:
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication@EnableEurekaServerpublic class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class); }}
通过设置不同profile,同时启动多个eureka实例,相互注册,在idea中同时启动两个eureka-server如下:
工具栏菜单 run -> edit configurations同时启动两个eureka server,访问 http://leo-node:8082/ 和 http://localhost:8081/如下:
下面进行eureka server客户端服务提供这 eureka-provider,pom依赖如下:
4.0.0 spring-cloud-test-001 com.leo.test 1.0.0-snapshot org.example service-provider-001 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-maven-plugin
eureka-provider配置application.yml配置如下:
eureka: client: service-url: defaultZone: http://leo-node:8081/eureka, http://leo-node:8082/eurekaspring: application: name: service-provider-001---spring: profiles: test-001-1server: port: 8091---spring: profiles: test-001-2server: port: 8092
编写启动类:
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication@EnableEurekaClientpublic class ServiceProviderApplication { public static void main(String[] args) { SpringApplication.run(ServiceProviderApplication.class); }}
编写controller服务提供接口:
import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/provider")public class HelloWorldController { @Value("${server.port}") private String port; @RequestMapping("/sayHello") public String sayHello(){ return "Hello world from "+port; }}
按照不同profile,启动两个eureka-provider服务提供端,
访问eureka server端,http://leo-node:8082和http://leo-node:8081/可以发现provider服务两个实例已经注册上来:4.0.0 spring-cloud-test-001 com.leo.test 1.0.0-snapshot org.example service-consumer-001 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-netflix-ribbon org.springframework.boot spring-boot-starter-actuator org.springframework.cloud spring-cloud-starter-netflix-hystrix org.springframework.cloud spring-cloud-starter-netflix-hystrix-dashboard org.springframework.boot spring-boot-maven-plugin
这里引入了hystrix,进行客户端的负载均衡和容错,
eureka-consumer-ribbon的配置application.xml如下:eureka: client: service-url: defaultZone: http://leo-node:8081/eurekaserver: port: 9000spring: application: name: service-consumer-ribbon-001#暴露全部的监控信息management: endpoints: web: exposure: include: "*"
编写启动类:
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.web.servlet.ServletRegistrationBean;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.hystrix.EnableHystrix;import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;import org.springframework.context.annotation.Bean;@SpringBootApplication@EnableDiscoveryClient@EnableHystrix@EnableHystrixDashboard // 启用hystrix dashboard功能public class ServiceConsumerRibbonApplication { public static void main(String[] args) { SpringApplication.run(ServiceConsumerRibbonApplication.class); } /** * 需要开启如下bean,才能正常访问 /hystrix 和 /hystrix.stream * @return */ @Bean public ServletRegistrationBean getServlet() { HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/hystrix.stream"); registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean; }}
ribbon的配置类如下:
@Configurationpublic class RibbonConfig { @LoadBalanced @Bean public RestTemplate newRestTemplate(){ SimpleClientHttpRequestFactory f = new SimpleClientHttpRequestFactory(); f.setConnectTimeout(1000); f.setReadTimeout(1000); return new RestTemplate(f); }}
对外controller如下:
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;@RestController@RequestMapping("/consumer/ribbon")public class ConsumerController { @Value(("${server.port}")) private String port; @Autowired private RestTemplate restTemplate; @RequestMapping("/sayHello") @HystrixCommand(fallbackMethod = "error") public String test(){ String providerMsg = restTemplate.getForObject("http://service-provider-001/provider/sayHello",String.class); return "from consumer and consumer port is "+port+" , provider msg is : "+providerMsg; } public String error(){ return "consumer ribbon error from hystrix"; }}
启动eureka-consumer-ribbon,访问 http://leo-node:9000/consumer/ribbon/sayHello:
显示:=======================================================================
=======================================================================
当将其中一个provider停止后,不断刷新则显示:可以看到请求的provider不存在或者发生错误时,hystric介入,返回了错误信息。
转载地址:http://vyme.baihongyu.com/