SpringCloud(2) 负载均衡器Ribbion, 远程调用Feign

实现远程调用的方法,以前用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
posted @ 2020-04-09 22:35  haohao1234  阅读(445)  评论(0编辑  收藏  举报