微服務調用方式

微服務調用方式之Ribbon

Ribbon簡介

Ribbon是Netflix發(fā)布的云中間層服務開源項目,其主要功能是提供客戶端實現負載均衡算法。Ribbon客戶端組件提供一系列完善的配置項如連接超時,重試等。簡單的說,Ribbon是一個客戶端負載均衡器,我們可以在配置文件中Load Balancer后面的所有機器,Ribbon會自動的幫助你基于某種規(guī)則(如簡單輪詢,隨機連接等)去連接這些機器,我們也很容易使用Ribbon實現自定義的負載均衡算法。

Ribbon的使用

通過IDEA創(chuàng)建項目并引入依賴
<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.yuan</groupId>
    <artifactId>order_service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>order_service</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

向注冊中心注冊服務(application.yml)

server:
  port: 8781

#指定注冊中心地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

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

使用Ribbon
啟動類中加入如下代碼:

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

使用添加@LoadBalanced注解后的RestTemplate調用服務提供者的接口時,可以使用虛擬IP替代真實IP地址。所謂的虛擬IP就是服務提供者在application.yml文件中配置的spring.application.name屬性的值。示例如下:(調用上篇文章中的)

@RestController
@RequestMapping("api/v1/order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

   //調用方式二
   @Autowired
   private LoadBalancerClient loadBalancer;

    @RequestMapping("save")
    public Object save(@RequestParam("user_id") int userId,@RequestParam("product_id") int productId){
        Object obj=restTemplate.getForObject("http://product-service/api/v1/product/findById?id="+productId,Object.class);

         //調用方式二
        //ServiceInstance instance = loadBalancer.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> productMap = restTemplate.getForObject(url, Map.class);

       return obj;

    }
}

啟動注冊中心 服務提供者和消費者

調用url進行測試

可以發(fā)現有負載均衡 默認調用為輪詢 每個端口被輪著調用

修改負載均衡策略(IRule實現類全路徑)
文檔:http://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/single/spring-cloud.html#_customizing_the_ribbon_client_by_setting_properties

#自定義負載均衡策略
product-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

如果部分機器配置強,則可以改為 WeightedResponseTimeRule

微服務調用方式之feign

Ribbon簡介

Feign是Netflix開發(fā)的聲明式、模塊化的HTTP客戶端,其靈感來自Retrofit、JAXRS-2.0以及WebSocket。Feign可幫組我們更加便捷、優(yōu)雅的調用HTTP API。
在Spring Cloud中,使用Feign非常簡單——創(chuàng)建一個接口,并在接口上添加一些注解,代碼就完成了。Feign支持多種注解,例如Feign自帶的注解或者JAX-RS注解等。

配置Feign

引入依賴:

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

啟動類增加注解@EnableFeignClients

@SpringBootApplication
@EnableFeignClients
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

yml配置:

server:
  port: 8781

#指定注冊中心地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

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

#修改調用超時時間
feign:
  client:
    config:
      default:
        connectTimeout: 2000
        readTimeout: 2000
Feign的使用
@FeignClient(name = "product-service")
public interface ProductClient {
    @GetMapping("/api/v1/product/find")
    String findById(@RequestParam(value = "id") int id);
}

上面是最簡單的feign client的使用,聲明完為feign client后,其他spring管理的類,如service就可以直接注入使用了,例如:

    @Autowired
    private ProductClient productClient;

    @Override
    public ProductOrder save(int userId, int productId) {
        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(jsonNode.get("name").toString());
        productOrder.setPrice(Integer.parseInt(jsonNode.get("price").toString()));
        return productOrder;
    }

可以看到,使用feign之后,我們調用eureka 注冊的其他服務,在代碼中就像各個service之間相互調用那么簡單。

Feign Client開啟日志

方式一:通過java bean的方式指定
@EnableFeignClients注解上有個defaultConfiguration屬性,可以指定默認Feign Client的一些配置。

@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration.class)
@SpringBootApplication
public class ProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class, args);
    }
}
@Configuration
public class DefaultFeignConfiguration {
    @Bean
    public Logger.Level feignLoggerLevel(){
        return Logger.Level.BASIC;
    }
}

方式二:通過配置文件指定

logging:
  level:
    com.xt.open.jmall.product.remote.feignclients.CartFeignClient: debug
Feign原理簡述
  • 啟動時,程序會進行包掃描,掃描所有包下所有@FeignClient注解的類,并將這些類注入到spring的IOC容器中。當定義的Feign中的接口被調用時,通過JDK的動態(tài)代理來生成RequestTemplate。
  • RequestTemplate中包含請求的所有信息,如請求參數,請求URL等。
  • RequestTemplate聲場Request,然后將Request交給client處理,這個client默認是JDK的HTTPUrlConnection,也可以是OKhttp、Apache的HTTPClient等。
  • 最后client封裝成LoadBaLanceClient,結合ribbon負載均衡地發(fā)起調用。
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 微服務架構模式的核心在于如何識別服務的邊界,設計出合理的微服務。但如果要將微服務架構運用到生產項目上,并且能夠發(fā)揮...
    java菜閱讀 3,045評論 0 6
  • 微服務架構模式的核心在于如何識別服務的邊界,設計出合理的微服務。但如果要將微服務架構運用到生產項目上,并且能夠發(fā)揮...
    程序員技術圈閱讀 2,838評論 10 27
  • ?通過前面兩章對Spring Cloud Ribbon和Spring Cloud Hystrix的介紹,我們已經掌...
    Chandler_玨瑜閱讀 214,498評論 15 140
  • 1 為什么需要服務發(fā)現 簡單來說,服務化的核心就是將傳統(tǒng)的一站式應用根據業(yè)務拆分成一個一個的服務,而微服務在這個基...
    謙小易閱讀 25,316評論 4 93
  • 理想的環(huán)境 光有基礎能力,享受自由僅僅具備了理論上的可能性。一個理想的環(huán)境,是享受自由的重要保障。 一個兩歲的小孩...
    李先琪閱讀 216評論 0 0

友情鏈接更多精彩內容