文档章节

大型分布式网络架构设计与实践笔记01. RPC

机器学习小蜜蜂
 机器学习小蜜蜂
发布于 2016/08/22 13:53
字数 1049
阅读 423
收藏 5

RPC

定义

RPC, Remote Process Call, 远程方法调用.

RPC 将本地调用转变为远程服务器上的调用,给系统的处理能力和吞吐量无限制提升提供了可能,是实现分布式计算的基础。

服务 Provider

扩容、服务隔离与分组 => 服务路由和负载均衡(router & load balance)

服务 consumer 通过 服务 provider的分组信息和地址信息进行路由,通常服务 provider 是一个集群,需要采用一定负载均衡策略,选取其中一台进行调用。

对象的序列化

序列化与反序列化

序列化: 将对象转化为二进制流的过程。

反序列化: 将二进制流转化为对象的过程。

常用的解决方案

Java build-in、Google's Protocal Buffers、Hessian; JSON, XML。

  • Protocal Buffers: 高性能,跨平台;需要编写 proto 文件,无法直接使用 Java 对象。
  • Hessian: 对各种语言的支持,性能稳定。
  • Java build-in: 无需引入第三方 jar、简单;但是性能不高。
  • JSON/XML: 跨平台,移动互联网领域广泛使用.

基于 TCP 协议实现 RPC

可以基于 Java 的 Socket API,实现一个简单 RPC 调用.

模型

基于 TCP 实现 RPC

Demo

|- ISayHello

|-- SayHelloService

|-- TCPRPCConsumer

|-- TCPRPCProvider

package com.land.rpc;

public interface ISayHello {
    public String sayHello(String arg);
}

package com.land.rpc;

public class SayHelloService implements ISayHello {

    public String sayHello(String arg) {
        if ("hello".equals(arg)) {
            return "hello";
        }

        return "bye";
    }
}
package com.land.rpc;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.Socket;

public class TCPRPCConsumer {

    public static void main(String[] args) throws NoSuchMethodException, IOException, ClassNotFoundException {
        final String interfaceName = ISayHello.class.getName();
        Method method = ISayHello.class.getMethod("sayHello", java.lang.String.class);
        Object[] methodArgs = {"hello"};
        Socket socket = new Socket("127.0.0.1", 4080);

        // 对象传输协议
        ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
        output.writeUTF(interfaceName);
        output.writeUTF(method.getName());
        output.writeObject(method.getParameterTypes());
        output.writeObject(methodArgs);

        ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
        // 阻塞式 I/O
        String result = (String)input.readObject();
        System.out.println(result);
    }
}
package com.land.rpc;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class TCPRPCProvider {

    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Map<String, Object> services = new HashMap<String, Object>();
        services.put("com.land.rpc.ISayHello", new SayHelloService());

        final ServerSocket server = new ServerSocket(4080);
        while (true) {
            Socket socket = server.accept();
            ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
            String interaceName = input.readUTF();
            String methodName = input.readUTF();
            Class<?>[] parameterTypes = (Class<?>[]) input.readObject();
            Object[] methodArgs = (Object[]) input.readObject();

            Object service = services.get(interaceName);

            Class<?> serviceInterfaceClass = Class.forName(interaceName);
            Method method = serviceInterfaceClass.getMethod(methodName, parameterTypes);
            Object result = method.invoke(service, methodArgs);
            ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
            output.writeObject(result);
        }
    }
}

基于 HTTP 协议实现 RPC

HTTP 请求与响应

  1. 浏览器根据所使用的 HTTP 协议,解析出 url 对应的域名。
  2. 通过 DNS 域名解析,查询出改域名对应的 IP 地址。
  3. 通过 url 解析出端口号(默认80)。
  4. 浏览器发起并建立该 IP 的 该端口的连接。
  5. 浏览器向服务器发起 GET/POST 请求。
  6. 服务器响应浏览器的请求,浏览器读取响应,渲染网页。
  7. 浏览器关闭与服务器的连接。

通过 HttpClient 发送 HTTP 请求

如果使用 Socket API 来处理 HTTP 请求,一方面工作量比较大,效果还不一定好(底层的流处理,并发控制 etc)。 HttpClient 提供了一个成熟的解决方案。

###RPC: HTTP vs. TCP

Protocol 优点 缺点
TCP 处于协议栈的下层,可以对协议字段进行定制,减少网络开销字节数,降低网络开销,提高性能,实现更大的吞吐量和并发数 实现成本高(需要考虑多线程并发、锁、I/O etc 复杂的底层细节),难以跨平台
HTTP 很多成熟的容器已经很好处理, like. Tomcat, Apache, Jboss; 成熟的响应格式,like. JSON, XML 处于协议栈的上层,同等内容信息比 TCP的字节数多,效率相对要低 => gzip 改善

RESTful & RPC URL 链接风格

两种主流的 URL:

风格 示例 备注
RPC http://hostname/provider.do?service=com.http.sayhello&format=json&timestamp=2016-09-05-20-36-00&arg1=arg1&arg2=arg2 hostname/format/timestamp/args
RESTful POST http://hostname/people GET http://hostname/people/land PUT http://hostname/people/land DELETE http://hostname/people/land RESTful = Representational State Transfer, 表现层状态转换. 利用了 HTTP 协议里的几种操作. POST: 创建,GET: 返回,PUT: 更新,DELETE: 删除
变通 POST arg1=hello arg2=123 URL http://hostname/provider/sayhelloservice/2016-09-05-20-36-00.json provider=服务提供方;sayhelloservice=服务接口名称;.json=服务端返回的数据格式;2016-09-05-20-36-00=客户端访问的时间戳

实现 HTTP RPC

可以使用 Servlet、Struts、Spring MVC 实现 HTTP RPC。

© 著作权归作者所有

机器学习小蜜蜂
粉丝 1
博文 2
码字总数 2270
作品 0
长宁
程序员
私信 提问
基于Tcp协议与基于Http协议的RPC简介笔记

前言:之前对于RPC方面的学习多限于对RMI原理的学习,直到今天在看陈康贤前辈的《大型分布式网站架构-设计与实践》这本书的时候,才发现原来RPC可以基于TCP协议也可以基于HTTP协议(这里所说...

浮躁的码农
2018/05/28
34
0
架构学习资料汇总

知名网站架构分析 探索Google App Engine背后的奥秘(1)–Google的核心技术 探索Google App Engine背后的奥秘(2)–Google的整体架构猜想 探索Google App Engine背后的奥秘(3)- Google App Eng...

peter8015
2016/04/22
302
0
大型网站架构系列:20本技术书籍推荐

学习是技术人员成长的基础,本次分享20本技术方面的书籍,这些书不是每一本都是经典,但是每一本都有其特点。以下20本大部分本人都看过,因此推荐给大家。(本次推荐的20本只是一个参考,比如...

xumaojun
2018/05/03
0
0
饿了么技术沙龙北京-架构专场

饿了么技术沙龙北京研发中心·架构专场【第二弹】 阿饿君回来了,福利再次登陆北京! 本次饿了么技术沙龙北京研发中心·架构专场邀请了58、头条、当当以及饿厂的主厨在等你,总有一盘会是你的...

eletech
2017/03/13
77
0
tech| 极客时间学习笔记 3

date: 2019-01-16 15:53:16 title: tech| 极客时间学习笔记 3 硅谷产品36讲 打造千万用户的世界级产品 idea/用户抱怨->实实在在有着卓越体验的产品; 团队->不同性格/不同经历/不同脑洞 工程师...

daydaygo
02/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Handler消息传递机制分析

Handler的用途和用法 写过Android程序的人大概都会遇到ANR(Application Not Responding)。如果程序在一段时间内没有响应,系统就会弹出一个对话框,让用户选择继续等待还是强制关闭应用。为...

tommwq
今天
5
0
JS前端MD5加密

Bootstrap官网获得md5 js地址:https://www.bootcdn.cn/blueimp-md5/ <!--MD5加密--><script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.js"></script> 使用方法: md5(pwd)......

被毒打的程序猿_先瑞
今天
6
0
BigDecimal 去后面无用的0的方法

BigDecimal a=new BigDecimal("0.1000"); System.out.println(a.stripTrailingZeros().toPlainString());...

xiaodong16
今天
7
0
JAVA--高级基础开发

[集合版双色球] 十二、双色球规则:双色球每注投注号码由6个红色球号码和1个蓝色球号码组成。红色球号码从1—33中选择;蓝色球号码从1—16中选择;请随机生成一注双色球号码。(要求同色号码...

李文杰-yaya
昨天
25
0
聊聊rocketmq broker的CONSUMER_SEND_MSG_BACK

序 本文主要研究一下rocketmq broker的CONSUMER_SEND_MSG_BACK CONSUMER_SEND_MSG_BACK rocketmq/common/src/main/java/org/apache/rocketmq/common/protocol/RequestCode.java public class......

go4it
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部