SpringCloud筆記三:服務消費者ribbon和feign和註冊中心高可用

SpringCloud筆記三:服務消費者ribbon和feign和註冊中心高可用

常用的服務間調用方式

  1. RPC調用方式

遠程過程調用,像調用本地服務一樣調用服務器的服務。

支持同步,異步調用。

客戶端和服務端之間建立TCP連接,可以一次建立一個,也可以多個調用複用一次連接。

​ 也就是說,建立連接後,每次調用就用這個連接,不需要再次連接了,因爲每次建立連接都會消耗資源的。(三次握手)

適合千萬級別的用戶。

Rpc數據包小,使用谷歌開源protobuf

開發成本高,編碼,序列化問題,丟包,分包。

  1. Rest(http)

http請求,支持各種協議和功能。

開發方便成本低。

http數據包大

微服務調用之ribbon實戰,訂單調用商品服務

  1. 開發步驟

1、創建order_service項目

2、開發僞下單接口

3、使用ribbon

​ 啓動類增加註解,這個是ribbon的負載均衡策略

​ @Bean

​ @LoadBalanced

​ public RestTemplate restTemplate(){

​ return new RestTemplate();

​ }

4、根據名稱進行調用商品,獲取商品詳情。

  1. ribbon介紹

類似於HttpClient,urlConnection

  1. 核心代碼
@Service
public class PorductOrderServiceImpl implements ProductOrderService {

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public ProductOrder save(int userId, int productId) {
        Object obj = restTemplate.getForObject("http://product-service/api/v1/product/find?id=" + productId, Object.class);
        System.out.println(obj);
        //獲取商品詳情
        ProductOrder productOrder=new ProductOrder();
        productOrder.setCreateTime(new Date());
        productOrder.setUserId(userId);
        productOrder.setTradeNo(UUID.randomUUID().toString());
        return productOrder;
    }
}
  1. 核心配置
server:
  port: 8781

#服務的名稱
spring:
  application:
    name: order-service

#指定註冊中心地址
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

Ribbon負載均衡源碼分析

  1. 引入rbbion的負載均衡器的第二種方式

通過注入:LoadBalancerClient,和在啓動類裏面添加Bean一樣。

@Service
public class PorductOrderServiceImpl implements ProductOrderService {

    /*@Autowired
    private RestTemplate restTemplate;*/

    @Autowired
    private LoadBalancerClient loadBalancerClient;


    @Override
    public ProductOrder save(int userId, int productId) {
        //Map<String,Object> productMap = restTemplate.getForObject("http://product-service/api/v1/product/find?id=" + productId, Map.class);
        //獲取商品詳情
        ServiceInstance instance = loadBalancerClient.choose("product-service");
        String url=String.format("http://%s:%s/api/v1/product/find?id="+productId,instance.getHost(),instance.getPort());
        RestTemplate restTemplate=new RestTemplate();
        Map<String,Object> productMap1 =restTemplate.getForObject(url,Map.class);
        ProductOrder productOrder=new ProductOrder();
        productOrder.setCreateTime(new Date());
        productOrder.setUserId(userId);
        productOrder.setTradeNo(UUID.randomUUID().toString());
        productOrder.setProductName(productMap.get("name").toString());
        productOrder.setPrice(Integer.parseInt(productMap.get("price").toString()));
        return productOrder;
    }
}
  1. 源碼分析ribbon的負載均衡類

ctrl+shift+N搜索LoadBalancerClient,查看chose()方法,通過源碼得知裏面的負載均衡策略。

調用負載均衡步驟
1、首先從註冊中心獲取provider的列表

​ 2、通過一定的策略選擇其中一個節點。

​ 3、再返回restTemplete調用。

調整ribbon的負載均衡策略

調整負載均衡策略官方文檔

  1. 在yml文件裏面進行配置

ribbon默認的負載均衡策略是:輪流進行,下面修改成隨機的。

#要調用的服務名
product-service:
		ribbon:
		    #找到IRule的實現類,並將該實現類的權限名copy過來。
			NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
  1. 策略配置

1、如果每個機器配置一樣,則建議不修改策略。(推薦)

2、如果部分機器配置強,則可以改爲 WeightedResponseTimeRule

微服務調用方式feign

  1. feign

Feign:僞RPC客戶端(本質還是http)

Feign官方文檔

  1. 使用步驟

1、加入依賴,注意新舊版本

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2、啓動類添加@EnableFeignClients註解

3、增加接口並@FeignClient(name=“所調用服務的註冊名字”)

@FeignClient(name = "product-service")
public interface ProductClient {

    @GetMapping("api/v1/product/find")
    String findById(@RequestParam(value = "id") int id);
}

4、實現類調用,將響應的json轉成JsonNode,然後從裏面取值。

@Service
public class PorductOrderServiceImpl implements ProductOrderService {

    /*@Autowired
    private RestTemplate restTemplate;*/

    /* @Autowired
    private LoadBalancerClient loadBalancerClient;*/

    @Autowired
    private ProductClient productClient;



    @Override
    public ProductOrder save(int userId, int productId) {
        //Map<String,Object> productMap = restTemplate.getForObject("http://product-service/api/v1/product/find?id=" + productId, Map.class);
        //獲取商品詳情
        /* ServiceInstance instance = loadBalancerClient.choose("product-service");
        String url=String.format("http://%s:%s/api/v1/product/find?id="+productId,instance.getHost(),instance.getPort());
        RestTemplate restTemplate=new RestTemplate();
        Map<String,Object> productMap1 =restTemplate.getForObject(url,Map.class);*/
        String response = productClient.findById(productId);
        JsonNode jsonNode = JsonUtils.str2JsonNode(response);

        ProductOrder productOrder=new ProductOrder();
        productOrder.setCreateTime(new Date());
        productOrder.setUserId(userId);
        productOrder.setTradeNo(UUID.randomUUID().toString());
        /*productOrder.setProductName(productMap.get("name").toString());
        productOrder.setPrice(Integer.parseInt(productMap.get("price").toString()));*/
        productOrder.setProductName(jsonNode.get("name").toString());
        productOrder.setPrice(Integer.parseInt(jsonNode.get("price").toString()));
        return productOrder;
    }
}

5、json轉JsonNode

public class JsonUtils {

    private static final ObjectMapper objectMapper=new ObjectMapper();

    public static JsonNode str2JsonNode(String str)  {

        try {
            return objectMapper.readTree(str);
        } catch (JsonProcessingException e) {
            return  null;
        }
    }
}

Feign源碼解讀以及Feign和Ribbon的選擇

  1. 設置當前線程睡眠
TimeUnit.SECONDS.sleep(10);//該方法會讓當前線程睡眠10s,睡眠會放棄cpu,但是不會放棄鎖對象。wait()會讓出cpu和鎖對象。該API還可以設置分鐘。
  1. 超時配置

默認options readtimeout是60,但是由於Hystrix默認是1s超時.下面是超時配置

#修改feign請求的超時時間
feign:
  client:
    config:
      default:
        connectTimeout: 2000
        readTimeout: 2000
  1. Feign內部的負載均衡策略其實使用的是ribbon
  2. 儘量使用Feign,因爲Feign解耦性更強。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章