高性能RPC(一)--java

RPC中的一些问题

1.数据协议

     序列化的方式(数据包的大小、序列化的优化)

     要支持更多的数据形式(xml,json等等)

      ---->自定义数据的协议头,自定义数据的结束。

2.IO模型

  2.1常见的IO模型

      ----->同步阻塞IO(Blocking IO):传统的IO模型

      ----->同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,

                      非阻塞的IO要求socket被设置为NONBLOCK.这里所说的NIO不是java不是java的NIO库(new io)

      ----->IO多路复用(IO Multiplexing):Reactor设计模式 也称为异步阻塞IO。

                                        java中的Selector和linux中的epoll都是这种模式

      ----->异步IO(Asynchronous IO) :Proactor设计模式 异步非阻塞IO。

      

  2.2同步和异步 : 用户线程和内核的交互方式

      ---->同步是指用户线程发起IO请求后,需要等待或者轮询你IO操作完成后才能继续执行

      ---->异步是指用户线程发起IO请求后,继续执行,当内核IO操作完成后会通知用户线程,或者调用用户线程注册回调函数

      

  2.3阻塞和非阻塞

           用户线程调用内核IO操作的方式,阻塞是指IO操作需要彻底完成后才能返回到用户空间,

          非阻塞是指IO操作被调用后立即返回用户一个状态,无需等到IO操作彻底完成后

          

          

  2.4 同步阻塞IO

   用户线程通过系统调用read发起IO操作,由用户空间转换到内核空间,

   内核等待数据包达到后,然后将接收到的数据拷贝到用户空间,完成read操作

      伪代码:{

        read(socket,buffer);

        process(buffer)

    }

    

  用户需要等待read将socket中的数据读取到buffer后,才能继续处理接收的数据,

  整个IO请求的过程中,用户线程是被苏泽的,导致用户在发起IO请求时,不能做

  任何事情,对CPU利用不够。

  

   2.5同步非阻塞IO

      在同步阻塞IO的基础上将Socket设置NONBLOCK。这样做用户线程可以在发起IO请求后立即返回.

    用户线程需要不断的发起IO请求,直到数据达到后,才能真正读取到数据,继续执行

     伪代码:{

     while(read(socket,buffer)!=SUCCESS){

        process(buffer);

     }

   }

   户线程可以在发起IO请求后立即返回.但是为了得到数据,仍需要不断轮询,重复请求,

  消耗了大量的CPU资源。很少直接使用这种模型

  

  

  2.6 多路复用IO

      IO多路复用建立在内核提供的多路分离函数select基础之上的,使用select

           函数可以避免同步非阻塞IO模型中的轮询等待问题。

          

      用户首先将需要进行的IO操作的socket添加到select中,然后阻塞等待select系统调用返回。

      当数据达到时,socket被激活,select函数返回。用户线程正式发起read请求,读取数据并

     继续执行 看起来比同步阻塞模型效率更差。但是,使用select以后最大的优势是用户可以

    在一个线程内同时处理多个socket的io请求,用户可以注册同个socket,然后不断调用select

    读取被激活的socket.达到同一个线程内同时处理多个IO请求

      伪代码{

         select(socket);

         while(1){

            sockets = select();

            for(Socket socket : sockets){

                if(can_read(socket)){

                   read(socket,buffer);

                   process(buffer);

                }

            }

         }

    }

    

    IO多路复用模型使用了Reactor设计模式实现了这一机制

    

    

   2.7 异步IO

         “真正“的异步IO需要操作系统更强的支持.

         异步IO模型中,当用户线程收到通知时,数据已经被内核读取完毕,并放在了用户线程

         指定的缓存区内,内核在IO完成后通知用户线程直接使用即可。

         

         

      操作系统支持并非特别完善,更多采用的是IO多路复用模拟异步IO方式

                                        

3.线程模型

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HRPC HRPC是一款基于Netty和Zookeeper设计的轻量级高性能RPC框架。特性采用Protostuff序列化;高性能,负载均衡;支持服务的注册和订阅;支持同步及异步2种调用方式;长连接,自动重连;采用cglib动态代理;代码简答,易上手;支持Spring;HRPC结构图服务注册中心服务端1. 通过Spring配置<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xmlns:context="http://www.springframework.org/schema/context"        xsi:schemaLocation="http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context.xsd">     <!--扫描需求发布的服务所在的包-->     <context:component-scan base-package="com.yingjun.rpc.service.impl"/>     <context:property-placeholder location="classpath:system.properties"/>     <!--服务端配置-->     <bean id="rpcServer" class="com.yingjun.rpc.server.RPCServer">         <constructor-arg name="zookeeper" value="${zookeeper.address}"/>         <constructor-arg name="serverAddress" value="${server.address}"/>     </bean> </beans>2. 服务接口public interface UserService {     public User getUser(String phone);     public User updateUser(User user); }3. 注册服务实现@HRPCService(UserService.class) public class UserServiceImpl implements UserService {     @Override     public User getUser(String phone) {         User user =new User(111,"yingjun",phone);         return user;     }     @Override     public User updateUser(User user) {         user.setName("yingjun@update");         return user;     } }客户端1. Spring配置<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xmlns:context="http://www.springframework.org/schema/context"        xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context.xsd">     <context:annotation-config/>     <context:property-placeholder location="classpath:system.properties"/>     <!--客户端配置-->     <bean id="rpcClient" class="com.yingjun.rpc.client.RPCClient">         <constructor-arg name="zookeeper" value="${zookeeper.address}"/>         <!--订阅需要用到的接口-->         <constructor-arg name="interfaces">             <list>                 <value>com.yingjun.rpc.service.OrderService</value>                 <value>com.yingjun.rpc.service.UserService</value>                 <value>com.yingjun.rpc.service.GoodsService</value>             </list>         </constructor-arg>     </bean> </beans>2. 同步调用UserService userService = rpcClient.createProxy(UserService.class); User user1 = userService.getUser("188888888"); logger.info("result:"   user1.toString());3. 异步调用AsyncRPCProxy asyncProxy = rpcClient.createAsyncProxy(UserService.class); asyncProxy.call("getUser", new AsyncRPCCallback() {      @Override      public void success(Object result) {          logger.info("result:"   result.toString());      }      @Override      public void fail(Exception e) {          logger.error("result:"   e.getMessage());      }  }, "188888888"); 标签:rpc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值