RPC远程过程调用
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思想:
Dubbo框架的工作原理图:
二、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技术 流程图