- В микросервисной архитектуре нам часто нужно взаимодействовать с другими сервисами для взаимодействия с данными.Есть два широко используемых метода.
- RPC
- HTTP
- В SpirngCloud по умолчанию используется HTTP для связи между микросервисами, из которых есть две наиболее часто используемые формы реализации.
- RestTemplate
- Feign
RestTempale
- На самом деле, в SpringWeb RestTemplate изначально поддерживается, но мы обычно используем URL-адрес запроса для записи напрямую, а не вызывая его в виде имени службы, но в микросервисной архитектуре, из-за существования реестра. Балансировка нагрузки может быть реализована без использования стороннего программного или аппаратного обеспечения.Все, наш лучший способ — получить доступ к экземпляру через имя службы, а стратегия балансировки нагрузки Ribbon решит за нас.
Первый способ (не рекомендуется)
@GetMapping("/RibbonServer/1")
public Map getRibbonServer1() {
// 新建对象
RestTemplate restTemplate = new RestTemplate();
//请求目标地址
String requestMsg = "方式一 GET 请求 RibbonServer";
Map response = restTemplate.getForObject("http://localhost:9999/RibbonServer/RibbonTest?requestMsg=" + requestMsg, Map.class);
log.info("response={}", response);
return response;
}
@PostMapping("/RibbonServer/1")
public Map postRibbonServer1() {
// 新建对象
RestTemplate restTemplate = new RestTemplate();
//请求目标地址
String requestMsg = "方式一 POST 请求 RibbonServer";
Map<String, Object> requestParam = new HashMap<>(16);
requestParam.put("requestMsg", requestMsg);
Map response = restTemplate.postForObject("http://localhost:9999/RibbonServer/RibbonTest", requestParam, Map.class);
log.info("response={}", response);
return response;
}
Используйте RestTemplate напрямую, URL записывается до смерти
второй способ
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/RibbonServer/2")
public Map getRibbonServer2() {
// 获取IP地址
ServiceInstance choose = loadBalancerClient.choose("RIBBON-SERVER");
String requestMsg = "方式二 GET 请求 RibbonServer";
String url = String.format("http://%s:%s", choose.getHost(), choose.getPort() + "/RibbonServer/RibbonTest?requestMsg=" + requestMsg);
RestTemplate restTemplate = new RestTemplate();
Map response = restTemplate.getForObject(url, Map.class);
log.info("response={}", response);
return response;
}
@PostMapping("/RibbonServer/2")
public Map postRibbonServer2() {
// 获取IP地址
ServiceInstance choose = loadBalancerClient.choose("RIBBON-SERVER");
// 组装URL
String url = String.format("http://%s:%s", choose.getHost(), choose.getPort() + "/RibbonServer/RibbonTest");
RestTemplate restTemplate = new RestTemplate();
String requestMsg = "方式二 POST 请求 RibbonServer";
Map<String, Object> requestParam = new HashMap<>(16);
requestParam.put("requestMsg", requestMsg);
Map response = restTemplate.postForObject(url, requestParam, Map.class);
log.info("response={}", response);
return response;
}
Используйте LoadBalancerClient, чтобы получить URL-адрес по имени приложения, а затем используйте RestTemplate для запроса.
Третий способ (рекомендуется)
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class RestTemplateConfig {
@Bean
@LoadBalanced //添加该注解,可以直接通过服务名找到对应的IP地址
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@Autowired
private RestTemplate restTemplate;
@GetMapping("/RibbonServer/3")
public Map getRibbonServer3() {
String requestMsg = "方式三 GET 请求 RibbonServer";
Map response = restTemplate.getForObject("http://RIBBON-SERVER/RibbonServer/RibbonTest?requestMsg=" + requestMsg, Map.class);
log.info("response={}", response);
return response;
}
@PostMapping("/RibbonServer/3")
public Map postRibbonServer3() {
String requestMsg = "方式三 POST 请求 RibbonServer";
Map response = restTemplate.postForObject("http://RIBBON-SERVER/RibbonServer/RibbonTest", getRequestParam(requestMsg), Map.class);
log.info("response={}", response);
return response;
}
Используя @LoadBalanced, имя приложения можно использовать непосредственно в RestTemplate.
Feign
- Feign – декларативный шаблонный HTTP-клиент, разработанный Netflix. Feign помогает нам быстрее и элегантнее вызывать HTTP API.
Шаги для использования
1. Импортируйте пакет OpenFeign (после SpringCloud2 Feign был переименован в OpenFeign)
<!--可以不导入ribbon,因为feign里面依赖了ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. Добавьте @EnableFeignClients в класс запуска.
@SpringBootApplication
@EnableFeignClients
public class SpringCloudRibbonClientApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudRibbonClientApplication.class, args);
}
}
3. Написать интерфейс для вызова указанного микросервиса (SDK может быть написан поставщиком интерфейса, мы можем вызвать его напрямую)
@FeignClient(name = "ribbon-server") //调用的服务名
public interface RibbonServerClient {
/**
* 测试请求 RibbonServer
* @Method: GET
* @author show
* @date 16:26 2019/6/9
* @param requestMsg 接口请求参数
* @return java.util.Map 接口返回值,建议用对象接收
*/
@GetMapping("/RibbonServer/RibbonTest")
Map getRibbonServer(@RequestParam("requestMsg") String requestMsg);
/**
* 测试请求 RibbonServer
* @Method: POST
* @author show
* @date 16:26 2019/6/9
* @param requestMsg 接口请求参数
* @return java.util.Map 接口返回值,建议用对象接收
*/
@PostMapping("/RibbonServer/RibbonTest")
Map PostRibbonServer(@RequestBody Map requestMsg);
}
4. Используя инъекцию зависимостей Spring, напрямую вызовите метод интерфейса, чтобы вызвать интерфейс службы ленточного сервера.
@RestController
@RequestMapping("/Feign")
@Slf4j
public class FeignController {
@Autowired
private RibbonServerClient ribbonServerClient;
/**
* Feign 访问微服务测试
* @author show
* @date 16:42 2019/6/9
* @return java.util.Map
*/
@GetMapping("/RibbonServer")
public Map getRibbonServer() {
String requestMsg = "Feign GET 请求 RibbonServer";
Map response = ribbonServerClient.getRibbonServer(requestMsg);
log.info("response={}", response);
return response;
}
/**
* Feign 访问微服务测试
* @author show
* @date 16:42 2019/6/9
* @return java.util.Map
*/
@PostMapping("/RibbonServer")
public Map postRibbonServer1() {
String requestMsg = "Feign Post 请求 RibbonServer";
Map<String, Object> map = new HashMap<>(16);
map.put("requestMsg", requestMsg);
Map response = ribbonServerClient.PostRibbonServer(map);
log.info("response={}", response);
return response;
}
}
-
Кодовый адрес проекта: