springcloud(四) ribbon和feign
Ribbon使用
order-service工程:

application.yml:
server: port: 9010 #order 服务都是用90 开头的端口 spring: application: name: microservice-consumer-order eureka: client: serviceUrl: defaultZone: http://peer1:8761/eureka/ instance: prefer-ip-address: true
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tuling.cloud</groupId>
<artifactId>microservice-consumer-order-ribbon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>05-ms-consumer-order-ribbon</name>
<!-- 引入spring boot的依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 已经包含了ribbon包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<!-- 引入spring cloud的依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 添加spring-boot的maven插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
ConsumerOrderApplication.java:
package com.jiagoushi.cloud.study;
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;
/**
* 演示默认的轮询的负载均衡
*/
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerOrderApplication {
@Bean
@LoadBalanced //ribbon的负载均衡注解,RestTemplate就具有了负载均衡
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerOrderApplication.class, args);
}
}
OrderController.java
package com.jiagoushi.cloud.study.user.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.jiagoushi.cloud.study.user.entity.User;
import java.util.HashMap;
import java.util.Map;
@RestController
public class OrderController {
private static final Logger LOGGER = LoggerFactory.getLogger(OrderController.class);
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/order")
public Map testOrder() {
Map<String ,Object> map = new HashMap<>();
map.put("测试服务是否启动","ok");
return map;
}
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://microservice-provider-user/" + id, User.class);
}
@GetMapping("/user/getIpAndPort")
public String getIpAndPort() {
return this.restTemplate.getForObject("http://microservice-provider-user/getIpAndPort", String.class);
}
@GetMapping("/log-user-instance")
public void logUserInstance() {
ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
// 打印当前选择的是哪个节点
OrderController.LOGGER.info("{}:{}:{}", serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort());
}
}
启动order服务调用user服务的时候就是采用了轮询。
user-service 工程:

UserController.java:
package com.jiagoushi.cloud.study.controller;
import com.jiagoushi.cloud.study.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class UserController {
@Autowired
private UserRepository userRepository;
@Autowired
private Registration registration;
@GetMapping("/user")
public Map testUser() {
Map<String,Object> map = new HashMap<>();
map.put("测试user服务","OK");
return map;
}
@GetMapping("/{id}")
public com.jiagoushi.cloud.study.entity.User findById(@PathVariable Long id) {
com.jiagoushi.cloud.study.entity.User findOne = userRepository.findOne(id);
return findOne;
}
@GetMapping("/getIpAndPort")
public String findById() {
return registration.getHost() + ":" + registration.getPort();
}
}

分别改为 8001 和 8002 端口启动,注册中心别忘了启动
注意:
测试结果:

发现order服务是轮询调用user服务的。
在配置文件可以指定某个服务使用Ribbon某个策略:

Ribbon脱离Eureka独立使用

Ribbon配置的优先级:属性配置 > JAVA配置(注解和配置类)>Netflix Ribbon默认配置
Feign使用
order-feign工程:

order 服务pom.xml 添加依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tuling.cloud</groupId>
<artifactId>microservice-consumer-order-feign</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<!-- 引入spring boot的依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- feign 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.tuling.cloud</groupId>
<artifactId>microservice-provider-user-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<!-- 引入spring cloud的依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 添加spring-boot的maven插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
ConsumerOrderApplication.java:
package com.jiagoushi.cloud.study;
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;
@EnableDiscoveryClient
@SpringBootApplication
// feign 支持
@EnableFeignClients
public class ConsumerOrderApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerOrderApplication.class, args);
}
}
OrderController.java
package com.jiagoushi.cloud.study.user.controller;
import com.jiagoushi.cloud.study.user.entity.User;
import com.jiagoushi.cloud.study.user.feign.RefactorUserService;
import com.jiagoushi.cloud.study.user.feign.UserFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderController {
@Autowired
private UserFeignClient userFeignClient; // 为了学习
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
return userFeignClient.findById2(id);
}
@GetMapping("/user-extends/{id}")
public com.jiagoushi.cloud.api.entity.User findById2(@PathVariable Long id) {
return refactorUserService.getUser(id);
}
}
UserFeignClient.java
package com.jiagoushi.cloud.study.user.feign;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.jiagoushi.cloud.study.user.entity.User;
@FeignClient(name = "microservice-provider-user")
public interface UserFeignClient {
@RequestMapping(value = "/{id}", method = RequestMethod.GET) //指名要调用的url
public User findById2(@PathVariable("id") Long id); // 方法名称随便写,但是最好与提供方一样,参数和提供方列表参数的顺序一致
}
欢迎来QQ群:592495675 一起研究 java技术,群里技术大佬,还有所有源代码
浙公网安备 33010602011771号