基于http协议实现RPC远程调用
今天简单说一下基本Http协议来实现RPC框架~
基于Http协议实现RPC框架:
优点:
1、简单、实用、开发方便
缺点:
1、性能不是很稳定,在海量数据时,完全顶不住,容易宕机
2、因为不是走的注册中心,不便于维护、监控以及统计分析
但是对于大多数公司而言,不会又像淘宝、京东那样大的数据量,所以基于Http协议的RPC,实现多个系统间的解耦,还是很实用的~
下面,我们进入正题,通过Java实现简单的RPC调用
一、maven 引入第三方jar包(不是maven项目,可以自己去网上下载一个对应的jar)
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.2</version> </dependency>
二、http的代码实现
1、简易版的Http请求
客户端代码:
@Test public void testHttpService() throws UnsupportedEncodingException { System.out.println("测试http请求开始~"); //封装请求参数 Map map = new HashMap<String, String>(); map.put("reqData","Hello World,世界你好~"); //http://localhost/testHttpService 请求的服务器地址URL String resp = HttpUtil.post("http://localhost/testHttpService", map); System.out.println("http服务返回结果为:"+ com.alibaba.fastjson.JSON.toJSON(resp)); }
服务端代码:
服务端 需要提供一个web服务以及相关的请求路径:http://localhost/testHttpService
@RequestMapping("/testHttpService") public void testHttpService(HttpServletRequest request,HttpServletResponse response) throws IOException { logger.info("测试HTTP请求 服务端开始~"); String reqData=request.getParameter("reqData"); //模拟 相关业务逻辑处理 logger.info("处理相关业务~reqData="+reqData); //模拟 返回业务结果 logger.info("业务处理完成,返回结果~"); Map mapResult=new HashMap(); mapResult.put("success",true); mapResult.put("code","0000"); mapResult.put("msg","http请求测试成功~"); //防止Http请求中文乱码 response.setHeader("Content-Type", "text/html;charset=utf-8"); PrintWriter printWriter=response.getWriter(); printWriter.write(com.alibaba.fastjson.JSON.toJSONString(mapResult)); printWriter.flush(); logger.info("测试HTTP请求 服务端结束~"); }
测试流程
1、启动WEB服务
2、客户端进行调用
输出结果:
测试http请求开始~ http服务返回结果为:{"code":"0000","msg":"http请求测试成功~","success":true}
2、升级版的Http请求调用
此处的升级重要是为了传参方便,服务器端不用每个参数都通过request获取到
1、创建一个传输参数的Bean类
package com.jd.test; /** * Created by zhanghao10 on 2017/4/17. */ public class MapParam { private String reqData;//请求数据 public String getReqData() { return reqData; } public void setReqData(String reqData) { this.reqData = reqData; } }
2、客户端代码:
@Test public void testHttpServiceEntity() throws IOException { System.out.println("测试http请求开始~"); //封装请求参数 Map map = new HashMap<String, String>(); map.put("reqData","Hello World,世界你好~"); //封装HTTP请求参数 HttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost("http://localhost/testHttpService"); List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>(); nameValuePairList.add(new BasicNameValuePair("reqData","Hello World,世界你好~")); httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairList,"UTF-8")); HttpResponse httpResponse=httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); String resp = EntityUtils.toString(httpEntity); System.out.println("http服务返回结果为:"+ com.alibaba.fastjson.JSON.toJSON(resp)); }
3、服务端代码
@RequestMapping("/testHttpService") public void testHttpService(MapParam mapParam,HttpSrvletRequest request,HttpServletResponse response) throws IOException { logger.info("测试HTTP请求 服务端开始~"+ com.alibaba.fastjson.JSON.toJSON(mapParam)); String reqData=request.getParameter("reqData"); //模拟 相关业务逻辑处理 logger.info("处理相关业务~reqData="+reqData); //模拟 返回业务结果 logger.info("业务处理完成,返回结果~"); Map mapResult=new HashMap(); mapResult.put("success",true); mapResult.put("code","0000"); mapResult.put("msg","http请求测试成功~"); //防止Http请求中文乱码 response.setHeader("Content-Type", "text/html;charset=utf-8"); PrintWriter printWriter=response.getWriter(); printWriter.write(com.alibaba.fastjson.JSON.toJSONString(mapResult)); printWriter.flush(); logger.info("测试HTTP请求 服务端结束~"); }
测试流程
1、启动WEB服务
2、客户端进行调用
测试结果:
测试http请求开始~ http服务返回结果为:{"code":"0000","msg":"http请求测试成功~","success":true}
是不是感觉很简单,没错,其实,你要是仔细看代码的话,你会发现,和我们正常的Servlet请求是一样的,不同的是
1、请求的时候需要用HttpClient来模拟浏览器端请求
2、服务器端返回结果 需要通过对应的流,而不是返回到界面
另外顺便说一下,这个项目是基于spring mvc实现的,其实也是Restful架构的具体实现方案~
推荐阅读连接:为什么需要RPC,而不是简单的HTTP接口?
怎样用通俗的语言解释什么叫 REST,以及什么是 RESTful?
联系方式