实现远程调用的方法,以前用httpclient,现在用restTemplate
1. 第一种方式RestTemplate
RestTemplate t = new RestTemplate(); String resp = t.getForObject("http://localhost:8081/msg", String.class);
2。第二种 LoadBalancerClient获取url地址再用RestTemplate
@Autowired
LoadBalancerClient loadBalancerClient;
。。。。。。
RestTemplate t = new RestTemplate(); ServiceInstance serviceInstance = loadBalancerClient.choose("PRODUCT"); String url = String.format("http://%s:%s/msg", serviceInstance.getHost(), serviceInstance.getPort()); String resp = t.getForObject(url,String.class);
这里有点问题 serviceInstance.getHost()获取不到真实IP?
3.@LoadBalanced注解
pom.xml
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> </dependencies>
application.yml
server:
port: 9500
eureka:
client:
service-url:
#注册服务端地址,多台server时,都注册
defaultZone: http://localhost:8001/eureka
spring:
application:
name: springcloud-ribbon-client
新增SpringcloudRibbonClientApplication
@EnableDiscoveryClient向服务中心注册
@SpringBootApplication @EnableDiscoveryClient public class SpringcloudRibbonClientApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudRibbonClientApplication.class, args); } }
@ LoadBalanced注解表明,这个restRemplate是需要做负载均衡的。
新建一个service类,用来调用在springcloud-eureka-client模块中的hello方法
@Component public class RestTemplateConfig { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } } public class ClientController { @Autowired RestTemplate restTemplate; @RequestMapping("/getProductMsg") public String getMsg() { // 第三种 @LoadBalanced注解,url中springcloud-eureka-client为应用的名字 String resp = restTemplate.getForObject("http://springcloud-eureka-client/hello",String.class); log.info("-------"+resp); return resp; } }
LoadBalanced内部使用ribbion做负载均衡
二。feign
2.1 它是声明式REST客户端(伪RPC),采用基于接口的注解
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
@EnableDiscoveryClient @SpringBootApplication @MapperScan("com.yjm.order.dao") @EnableFeignClients public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
@FeignClient(name="product") public interface ProductClient { @GetMapping("/msg") String getMsg(); }
name="product" 定义的服务的名称,@GetMapping("/msg")路径与要调用的接口路径一致
@RestController @Slf4j public class ClientController { @Autowired ProductClient productClient; @RequestMapping("/getProductMsg") public String getMsg() { String resp = productClient.getMsg(); log.info(resp); return resp; } }
2.2 上面是将feign调用定义在调用方order侧,实际应该定义在服务提供侧product,因为接口的格式内容都是product定义的
product拆分了module product-client专门提供服务调用
package org.product.client; @FeignClient(name="product") public interface ProductClient { @GetMapping("/msg") // Feign参数前面什么都不加,默认是@RequestBody String getMsg(@RequestParam String id); @PostMapping("/getProductList") List<ProductInfoOutput> getProductList(@RequestBody List<String> productIdList); @PostMapping("/decreaseStock") void decreaseStock(@RequestBody List<DecreaseStockInput> cartList); }
Order侧pom中引入product-client的依赖
<dependency> <groupId>com.yy</groupId> <artifactId>product-common</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.yy</groupId> <artifactId>product-client</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
orderApplication.java添加feignClient注解写明basePackage不然扫描不到依赖包中
@EnableDiscoveryClient @SpringBootApplication @MapperScan("com.yjm.order.dao") @EnableFeignClients(basePackages = "org.product.client") public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
service中可以直接注入类使用了
@Autowired
ProductClient productClient;
参考文章:https://www.cnblogs.com/haly/p/10840119.html