美文网首页
微服务调用方式

微服务调用方式

作者: 二圈儿 | 来源:发表于2019-04-28 09:44 被阅读0次

微服务调用方式之Ribbon

Ribbon简介

Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户端实现负载均衡算法。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中Load Balancer后面的所有机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。

Ribbon的使用
通过IDEA创建项目并引入依赖
<?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进行测试

可以发现有负载均衡 默认调用为轮询 每个端口被轮着调用

修改负载均衡策略(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开发的声明式、模块化的HTTP客户端,其灵感来自Retrofit、JAXRS-2.0以及WebSocket。Feign可帮组我们更加便捷、优雅的调用HTTP API。
在Spring Cloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。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的动态代理来生成RequestTemplate。
  • RequestTemplate中包含请求的所有信息,如请求参数,请求URL等。
  • RequestTemplate声场Request,然后将Request交给client处理,这个client默认是JDK的HTTPUrlConnection,也可以是OKhttp、Apache的HTTPClient等。
  • 最后client封装成LoadBaLanceClient,结合ribbon负载均衡地发起调用。

相关文章

  • Java进阶-Dubbo-进阶

    一、服务调用过程 1.1 服务调用方式   Dubbo 服务调用过程:   Dubbo 支持同步和异步两种调用方式...

  • Alibaba 服务调用

    1. 调用服务的方式有多种这边只展示采用restTemplate方式调用开发一个服务接口地 消费者调用 第二种方式...

  • golang RPC

    1、RPC流水线工程 ① Client以本地调用的方式调用服务 ② Client Stub接收到调用后,把服务调用...

  • 微服务调用方式

    微服务调用方式之Ribbon Ribbon简介 Ribbon是Netflix发布的云中间层服务开源项目,其主要功能...

  • 四、应用通信

    一、两种应用间的通信方式 二、Spring Cloud中两种restful调用方式:(示例:用订单服务调用商品服务...

  • 微服务服务的调用方式

    服务之间是怎么通信的? 两种方式:rpc和http RPC远程服务调用,将请求序列化,通过网络传输,在接收端进行反...

  • 微服务系列-架构介绍

    服务调用的流程 RESTful API 方式的服务描述例子: XML 配置方式多用作 RPC 协议的服务描述,通过...

  • 2019-08-03 图解RPC

    一次 RPC 调用流程如下: • 服务消费者(Client 客户端)通过本地调用的方式调用服务。 •客户端存根(C...

  • rpc-dubbo

    如果有一种方式能让我们像调用本地服务一样调用远程服务,而让调用者对网络通信这些细节透明。这种方式其实就是RPC(R...

  • SpringCloud微服务治理一(介绍,环境搭建,Eureka

    1.远程调用方式 了解一下微服务的调用方式 1.1.RPC RPC,即 Remote Procedure Call...

网友评论

      本文标题:微服务调用方式

      本文链接:https://www.haomeiwen.com/subject/knhknqtx.html