一个简单的微服务系统:服务注册和发现,服务消费,负载均衡,断路器,智能路由,配置管理
服务注册中心:
eureka是一个高可用组件,没有后端缓存,每一个实例注册后向注册中心发送心跳,默认情况下,erureka server也是一个eureka clinet,必须指定server
引入依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency>
启用注册中心:
@EnableEurekaServer @SpringBootApplication public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } }
YML配置:
server:
port: 8761
spring:
application:
name: microservice-registry
profiles:
active: native
eureka:
instance:
prefer-ip-address: true
client:
registerWithEureka: false
fetchRegistry: false
#serverUrl:
# defaultZone: http://otherRegistry:port/eureka/
eureka客户端:
依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
启动:
@SpringBootApplication @EnableDiscoveryClient @RestController public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } @RequestMapping("/hi") public String home(@RequestParam String name) { return "hi "+name+",i am from port: " +port; } }
YML配置:
spring: application: name: microservice-producer profiles: active: native eureka: instance: prefer-ip-address: true client: serviceUrl: defaultZone: http://localhost:8761/eureka/
在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务间基于http restful
springcloud有两种服务调用方式:ribbon+restTemplate和feign,ribbon是一个负载均衡客户端,可以很好控制http和tcp的一些行为,feign默认集成也ribbon
ribbon+restTemplate:
依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency>
启动:
@SpringBootApplication @EnableDiscoveryClient public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } }
调用:
@Service public class HelloService { @Autowired RestTemplate restTemplate; public String hiService(String name) { return restTemplate.getForObject("http://eureka-producer/hi?name="+name,String.class); } }
YML配置:
spring: application: name: microservice-ribbon-consumer profiles: active: native eureka: instance: prefer-ip-address: true client: serviceUrl: defaultZone: http://localhost:8761/eureka/
feign:
依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency>
启动:
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } }
调用:
@RestController public class HiController { @Autowired SchedualServiceHi schedualServiceHi; @RequestMapping(value = "/hi",method = RequestMethod.GET) public String sayHi(@RequestParam String name){ return schedualServiceHi.sayHiFromClientOne(name); } } @FeignClient(value = "eureka-producer") public interface SchedualServiceHi { @RequestMapping(value = "/hi",method = RequestMethod.GET) String sayHiFromClientOne(@RequestParam(value = "name") String name); }
yml配置:
spring: application: name: microservice-feign-consumer profiles: active: native eureka: instance: prefer-ip-address: true client: serviceUrl: defaultZone: http://localhost:8761/eureka/
断路器:应付故障传播问题
ribbon+restTemplate:
依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
启动:
@SpringBootApplication @EnableDiscoveryClient @EnableHystrix public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } }
使用:
@Service public class HelloService { @Autowired RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "hiError") public String hiService(String name) { return restTemplate.getForObject("http://eureka-producer/hi?name="+name,String.class); } public String hiError(String name) { return "hi,"+name+",sorry,error!"; } }
YML中不需要额外配置
feign:
依赖同上
启动:
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients @EnableCircuitBreaker public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } }
使用:
@FeignClient(value = "eureka-producer", fallback = SchedualServiceHiHystric.class) public interface SchedualServiceHi { @RequestMapping(value = "/hi",method = RequestMethod.GET) String sayHiFromClientOne(@RequestParam(value = "name") String name); } @Component public class SchedualServiceHiHystric implements SchedualServiceHi { @Override public String sayHiFromClientOne(String name) { return "sorry "+name; } }
yml配置:
额外添加:
feign:
hystrix:
enabled:true
路由网关:
依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency>
启动:
@EnableZuulProxy @EnableDiscoveryClient @SpringBootApplication public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } }
yml配置:
spring: application: name: microservice-gateway profiles: active: native eureka: instance: prefer-ip-address: true client: serviceUrl: defaultZone: http://localhost:8761/eureka/ zuul: routes: microservice-producer: path: /produce/** serviceId: microservice-producer
配置管理:
服务器依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency>
客户端依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
服务器端启动:
@EnableDiscoveryClient @SpringBootApplication @EnableConfigServer public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } }
客户端启动不需要额外添加
服务器端yml配置:
server: port: 8000 spring: application: name: microservice-config cloud: config: server: native: search-locations: classpath:/repo profiles: active: native eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/
客户端yml配置:
spring: application: name: microservice-gateway cloud: config: uri: http://localhost:8000 fail-fast: true profiles: active: native eureka: instance: prefer-ip-address: true client: serviceUrl: defaultZone: http://localhost:8761/eureka/
监控管理:
依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-turbine</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-turbine</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency>
启动:
@SpringBootApplication @EnableTurbine @EnableDiscoveryClient @EnableHystrixDashboard public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } }
yml配置:
server: port: 8770 security.basic.enabled: false turbine: aggregator: clusterConfig: default # 指定聚合哪些集群,多个使用","分割,默认为default。可使用http://.../turbine.stream?cluster={clusterConfig之一}访问 appConfig: microservice-feign-consumer,microservice-ribbon-consumer ### 配置Eureka中的serviceId列表,表明监控哪些服务 clusterNameExpression: new String("default") # 1. clusterNameExpression指定集群名称,默认表达式appName;此时:turbine.aggregator.clusterConfig需要配置想要监控的应用名称 # 2. 当clusterNameExpression: default时,turbine.aggregator.clusterConfig可以不写,因为默认就是default # 3. 当clusterNameExpression: metadata['cluster']时,假设想要监控的应用配置了eureka.instance.metadata-map.cluster: ABC,则需要配置,同时turbine.aggregator.clusterConfig: ABC
消息总线:将分布式节点用轻量的消息代理连接起来,可用于广播配置文件的更改或者服务之间的通讯,也可用于监控