微服务之服务间调用(ribbon)

RPC(remote produce call远程过程调用)与HTTP

RPC:类似的还有RMI,底层都是基于原生TCP(传输控制协议)通信,速度快,效率高,但灵活性低,限定技术,语言, 早期的webservice,现在热门的dubbo(阿里开发的),都是基于rpc。
HTTP:基于TCP,但规定了数据的传输格式,缺点:消息封装臃肿,效率较低。优点:对服务提供的调用方法没有任何的技术限定,自由灵活,更符合微服务的概念。rest风格就是HTTP实现的。

基于http的spring模板工具类RestTemplate

用处:实现跨服务的调用通过resttemplate调用url 与类对象。分布式服务
resttemplate模板工具类目前支持三种客户端工具:
1、Httpclient
2、OkHttp
3、JDK原生的HttpurlConnection(默认)
上源码:

//在调用者的启动器里面添加RestTemplate
@SpringBootApplication
public class ConsumerApplication {
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();//使用默认的http客户端工具
    }

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class,args);
    }
}

在控制器里通过resttemplate调用其他服务的处理结果,实现了服务之间的调用,下面的url是被调用服务的url地址,结果返回为User。
源码位于我的github:https://github.com/zhudinghuan/Remote-Procedure-Call-Protocol 有兴趣可以看看。

@Controller
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;
@ResponseBody
    @RequestMapping("hello")
    private User query(){
        String url="http://localhost:8081/hello";
        User user=restTemplate.getForObject(url,User.class);
        return user;
    }
}

springcloud简介

springcloud将目前非常流行的一些技术整合在一起,实现了诸如:配置管理,服务发现,智能路由,负载均衡,熔断器,控制总线,集群状态等功能。
主要包括以下组件:
在这里插入图片描述

Eureka注册中心管理服务

利用resttemplate写死需要调用的服务的弊端:

1、url地址写在代码里不方便后期修改‘
2、如果被调用的服务宕机,调用者无法感知
3、无法做到负载均衡

eureka原理图:
在这里插入图片描述

逻辑过程:
运行起来的每一个服务都会向注册中心进行注册,提交自己的服务名,地址,以及实例对象,并且在设置时间间隔内进行续约,更新状态,已经挂掉的服务会被剔除,保证服务的有效性。在调用时,服务调用者通过拉取注册中心的服务列表,获得服务的基本信息,再通过url进行调用。

第一种方式:不实现负载均衡的方式实现通过注册中心进行调用

在搭建好注册中心以及注册好服务之后,可以通过注入DiscoveryClient discoveryClient,实现对注册中心数据的拉取,实现通过注册中心来调用服务。具体代码如下:

package com.example.consumeservice.Controller;


import com.example.consumeservice.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@Controller
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping("hello")
    @ResponseBody
    private User query(){
//通过名称拉取注册列表
        List<ServiceInstance> list=discoveryClient.getInstances("USER-SERVER");
//第一个服务
        ServiceInstance instanceInfo=list.get(0);

        String url="http://"+instanceInfo.getHost()+":"+instanceInfo.getPort()+"/hello";
        User user=restTemplate.getForObject(url,User.class);
        return user;

    }
}

注意:
在注入DiscoveryClient时,是注入import org.springframework.cloud.client.discovery.DiscoveryClient这个包下的

第二种方式:实现负载均衡的方式实现通过注册中心进行调用?

负载均衡是什么

负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。

怎样实现?

1、随机
2、轮询
3、hash
我们通过ribbon实现负载均衡,因为它内置负载均衡算法。

第一步pom文件

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

第二步加注解(在resttemplate上面添加 @LoadBalanced)

package com.example.consumeservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
//import org.springframework.web.client.RestTemplate;

@EnableDiscoveryClient
@SpringBootApplication
public class ConsumeServiceApplication {
    @Bean
    @LoadBalanced
    //内置拦截器,拦截resttemplate请求
    public RestTemplate restTemplate(){
        return new RestTemplate();//使用默认的http客户端工具
    }

    public static void main(String[] args) {
        SpringApplication.run(ConsumeServiceApplication.class, args);
    }

}

第三步使用

默认采用轮询的方式,采用其他方法改yml
在这里插入图片描述

 private User query(){
 //用服务名称USER-SERVER直接取代主机号加端口
    String url="http://USER-SERVER/hello";
        User user=restTemplate.getForObject(url,User.class);
        return user;

    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值