一、Consul注册中心
1.访问Consul官网,下载Consul服务,地址:https://www.consul.io/downloads
2.给某个微服务mango-monitor的pom.xml文件添加Consul依赖
</dependencies>
<!--consul-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
</dependencies>
<!--srping cloud-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3.修改配置文件application.yaml
server:
port: 8000
spring:
application:
name: mango-monitor
cloud:
consul:
host: localhost
port: 8500
discovery:
serviceName: ${spring.application.name} # 注册到consul的服务名称
# 开放健康检查接口
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: ALWAYS
4.修改启动类,添加@EnableDiscoveryClient注解
@EnableAdminServer
@EnableDiscoveryClient
@SpringBootApplication
public class MangoMonitorApplication {
public static void main(String[] args) {
SpringApplication.run(MangoMonitorApplication.class, args);
}
}
二、服务消费
使用Ribbon进行负载均衡,使用Feign进行声明式服务调用。Feign封装了Ribbon。
1.给服务提供者和服务消费者的pom.xml添加依赖
<!--服务监控-->
</dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${spring.boot.admin.version}</version>
</dependency>
<!--consul-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
对于Feign要引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.添加配置application.yaml
server:
port: 8003
spring:
application:
name: mango-producer
cloud:
consul:
host: localhost
port: 8500
discovery:
serviceName: ${spring.application.name} # 注册到consul的服务名称
boot:
admin:
client:
url: "http://localhost:8000"
# 开放健康检查接口
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: ALWAYS
3.修改启动类
@EnableDiscoveryClient
@SpringBootApplication
public class MangoProducerApplication {
public static void main(String[] args) {
SpringApplication.run(MangoProducerApplication.class, args);
}
}
4.对于服务消费者,可以注入服务发现客户端和负载均衡客户端
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ServiceController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private DiscoveryClient discoveryClient;
/**
* 获取所有服务
*/
@RequestMapping("/services")
public Object services() {
return discoveryClient.getInstances("mango-producer");
}
/**
* 从所有服务中选择一个服务(轮询),大多数采用这种方式调用
*/
@RequestMapping("/discover")
public Object discover() {
return loadBalancerClient.choose("mango-producer").getUri().toString();
}
}
@RestController
public class CallHelloController {
@Autowired
private LoadBalancerClient loadBalancer;
@RequestMapping("/call")
public String call() {
ServiceInstance serviceInstance = loadBalancer.choose("mango-producer");
System.out.println("服务地址:" + serviceInstance.getUri());
System.out.println("服务名称:" + serviceInstance.getServiceId());
//通过RestTemplate远程调用
String callServiceResult = new RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello", String.class);
System.out.println(callServiceResult);
return callServiceResult;
}
}
5.实际负载均衡的调用,修改启动类,注入RestTemplate
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class MangoConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(MangoConsumerApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@RestController
public class RibbonHelloController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/ribbon/call")
public String call() {
// 调用服务, service-producer为注册的服务名称,LoadBalancerInterceptor会拦截调用并根据服务名找到对应的服务
String callServiceResult = restTemplate.getForObject("http://mango-producer/hello", String.class);
return callServiceResult;
}
}
三、服务熔断(Hystrix)
因为Feign已经依赖Hystrix了,所以maven上不用做配置。
1.修改application.yaml文件
# 开启熔断器
feign:
hystrix:
enabled: true
2.创建回调类,添加fallback属性
@FeignClient(name = "mango-producer", fallback = MangoProducerHystrix.class)
public interface MangoProducerService {
@RequestMapping("/hello")
public String hello();
}
@Component
public class MangoProducerHystrix implements MangoProducerService {
@RequestMapping("/hello")
public String hello() {
return "sorry, hello service call failed.";
}
}
四、服务网关
1.添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
2.修改启动类,添加注解@EnableZuulProxy
@EnableZuulProxy
@SpringBootApplication
public class MangoZuulApplication {
public static void main(String[] args) {
SpringApplication.run(MangoZuulApplication.class, args);
}
}
3.修改配置文件
server:
port: 8010
spring:
application:
name: mango-zuul
cloud:
consul:
host: localhost
port: 8500
discovery:
serviceName: ${spring.application.name} # 注册到consul的服务名称
zuul:
routes:
ribbon:
path: /ribbon/**
serviceId: mango-consumer # 转发到消费者 /ribbon/
feign:
path: /feign/**
serviceId: mango-consumer # 转发到消费者 /feign/