欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RPC远程过程调用

程序员文章站 2022-06-15 17:14:33
...

RPC远程过程调用 方式有:
1.跨域 方式

(跨域方式有:
Jsonp跨域--------利用标签中的src属性 和 JSONPObject对象
CORS跨域--------利用配置类 )
2.HttpClient技术 方式
3.Dubbo框架 方式

一、Dubbo框架 实现远程过程调用
1.父级项目 Pom.xml文件添加Dubbo依赖
2.提供者 和 消费者 项目 的pom.xml文件,都要添加依赖 中立接口项目
3.提供者 和 消费者 项目 的.yml配置文件,都要添加Dubbo配置

<!--引入dubbo配置 -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>

服务提供者的 .yml配置文件:

#关于Dubbo配置
dubbo:
  scan:
    basePackages: com.jt    #指定dubbo的包路径,主要扫描的是实现类
  application:              #应用名称 (即提供者的名字)
    name: provider-sso     #一个接口对应一个服务名称(一个接口只能有一个实现类,是dubbo框架的规则)
  registry:                 #zk集群 主机中的信息与从机中的信息一致的 从zk中获取数据的时候链接的从机 主机的作用就是监控集群
  	#注册中心的地址:连接的一般是从机的IP(主机的信息与从机的信息一致,从zookeeper中获取数据的时候连接的是从机。主机的作用是监控集群允许状态,负责数据的同步)
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
  protocol:  #指定协议
    name: dubbo  #使用dubbo协议(tcp-ip)  web-controller直接调用sso-Service
    port: 20880  #每一个服务都有自己特定的端口 不能重复.

消费者的 .yml配置文件:

#关于Dubbo配置
dubbo:
  scan:
    basePackages: com.jt
  application:
    name: consumer-web   #定义消费者名称
  registry:               #注册中心地址
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183

服务提供者 业务层代码–案例
注意:类上 @Service注解 导入的包是 alibaba.dubbo的包,不是spring的。

package com.jt.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import com.jt.util.ObjectMapperUtil;
import com.jt.vo.SysResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import redis.clients.jedis.JedisCluster;

import java.util.UUID;

@Service    //dubbo的注解
public class DubboUserServiceImpl implements DubboUserService{

    @Autowired
    private UserMapper userMapper;
   
}

消费者控制层代码—案例
注意:用@Reference注解注入提供者对象,
check属性------表示 项目启动时先启动谁
timeout属性—表示 RPC远程调用连接超时时间
loadbalance属性----表示 实现负载均衡策略

Dubbo负载均衡的方式: 名称都是类名的前半部分都小写即可.
1.RandomLoadBalance 随机负载均衡 语法: random 默认的
2.RoundRobinLoadBalance 轮询策略 语法: roundrobin
3.ConsistentHashLoadBalance 一致性hash算法 将消费者与服务提供者绑定 语法: consistenthash
4.LeastActiveLoadBalance 挑选负载压力小的服务器进行访问 语法: leastactive

package com.jt.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.service.DubboUserService;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller //由于设计到页面跳转功能.
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;
    
    @Reference(check = false,timeout = 3000,loadbalance = "leastactive")
    private DubboUserService dubboUserService;
 
}

SOA思想:
RPC远程过程调用

Dubbo框架的工作原理图:
RPC远程过程调用

二、Jsonp跨域 原理步骤:
1.利用javascrpit中的src属性实现跨域请求.
2.自定义回调函数 function callback(xxxx);
3.将返回值结果进行特殊的格式封装 callback(json);
4.由于利用src属性进行调用 所以只能支持get请求类型.

JSONPObject对象实现JSONP跨域,代码:

package com.jt.web.controller;

import com.fasterxml.jackson.databind.util.JSONPObject;
import com.jt.pojo.ItemDesc;
import com.jt.util.ObjectMapperUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class JSONPController {

    @RequestMapping("/web/testJSONP")
    public JSONPObject jsonp(String callback){
        ItemDesc itemDesc = new ItemDesc();
        itemDesc.setItemId(100L).setItemDesc("API测试!!!");
        return new JSONPObject(callback, itemDesc);   //callback是回调函数的名称
    }

三、CORS跨域 --利用配置类实现跨域

package com.jt.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CORSConfig implements WebMvcConfigurer {     //实现WebMvcConfigurer接口

    /**
     * 实现跨域的方式
     * 需要配置服务端程序
     * 方法说明:
     *      1.addMapping(/**) 允许什么样的请求可以跨域  所有的请求
     *      2.allowedOrigins("*")可以允许任意的域名
     *      3.allowCredentials(true) 跨域时是否允许携带cookie等参数
     */
    @Override   //重写方法
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true);
    }
}

四、HttpClient技术 方式实现远程调用:
浏览器解析ajax发起跨域请求.程序虽然可以正确的调用,但是浏览器可以监控用户的所有的参数及返回值.在一些特定的条件下该操作不安全.
一般使用跨域的请求都是用来获取其他服务器的数据(查询操作),如果遇到了POST需要提交的参数应该使用更加安全的请求方式实现(即HttpClient技术).

httpClient对象 里工具API

<!--添加httpClient jar包 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
@Service
public class UserServiceImpl implements UserService{


    /**
     * 利用HttpClient对象的API工具
     * 由jt-web向jt-sso进行数据的请求.之后获取数据.
     * @param userId
     * @return
     */
    @Override
    public User findUserById(Long userId) {
        //1.定义url地址
        String url = "http://sso.jt.com/user/findUserById/"+userId;
        HttpClient httpClient = HttpClients.createDefault();  //创建默认连接
        HttpGet httpGet = new HttpGet(url);  //创建get请求
        try {
            //发起请求,得到响应
            HttpResponse httpResponse = httpClient.execute(httpGet);
            if(httpResponse.getStatusLine().getStatusCode() == 200){
                HttpEntity httpEntity = httpResponse.getEntity(); //获取响应信息里的实体对象
                //json格式(因为返回来的是json格式,一定要指定字符集编码,不然会乱码)
                String result = EntityUtils.toString(httpEntity, "UTF-8");
                //把json串转换为对象类型
                return ObjectMapperUtil.toObject(result, User.class);
            }else{
                throw new RuntimeException("请求失败,请校验地址信息");
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}

HttpClient技术 流程图
RPC远程过程调用