一个基于Netty和Spring实现的Rpc框架

作者: 一字马胡
转载标志 【2017-11-03】

更新日志

日期 更新内容 备注
2017-11-03 添加转载标志 持续更新

项目地址:https://github.com/pandening/Nsrpc

ok-rpc

ok-rpc是一个轻量级、学习型的rpc框架,使用了流行的NIO框架Netty作为底层数据传输介质,使用Spring容器框架管理bean,使用Zookeeper来做服务注册和服务发现。未来还会添加更多有趣的技术到这里面来,所以ok-rpc的将一直不断的更新,或多或少的添加新的内容,使其逐渐完善,并走向功能丰富、性能卓越的方向。

性能和功能点是目前ok-rpc框架首要考虑的关键点,目前的ok-rpc性能并不可观,资源占用非常大,日后需要尽快不断的优化完善。

在设计上,ok-rpc希望一台机器部署一个ok-rpc的服务端或者客户端,而一个服务端希望可以使用一个[ip:pot]对外提供服务,一个ok-rpc客户端则可以访问任意可达的服务,未来会做权限控制,关于checklist和todolist将在下文中提到。

ok-rpc的服务端启动之初,就会加载所有注册的服务,服务想要对外发布就需要通过ok-rpc的服务端进行对外暴露,而ok-rpc使用了Spring强大得bean管理能力接管了暴露服务的任务,同样客户端在启动之初同样会使用Spring的强大力量来初始化service的引用,ok-rpc的服务端与客户端之间通过Netty进行数据传输(request和response),目前仅仅支持基于Tpc的传输,而且协议极为简单,未来将重新设计通信协议,包括codec协商、loadBalance等等内容。ok-rpc使用了各种技术来管理远端服务和客户端调用,使得服务端的服务暴露异常简单,客户端的调用就好像是在本地调用一样。

ok-rpc的名字源于okHttp和okIo,对于ok开头的框架都是非常厉害的,介于希望ok-rpc也能逐渐走向牛逼之路,所以取名字为“ok-rpc”,至于为什么中间添加了“-”,也就意味着离OkHttp、OkIo等框架还要很远的路要走。

ok-rpc的使用

使用ok-rpc异常简单,下面是一个简单的示例。

  1. 服务端暴露服务

你需要编写一个接口,比如下面的这个:

package io.hujian.rpc.test.client;

/**
 * Created by HuJian on 2017/10/5.
 *
 */
public interface EchoService {

    String echo(String msg);

}

对于服务端来说,你还需要编写实现类:

package io.hujian.rpc.test.server;

import io.hujian.npc.manager.RpcService;
import io.hujian.rpc.test.client.EchoService;

/**
 * Created by HuJian on 2017/10/5.
 *
 * impl
 */
@RpcService(EchoService.class)
public class EchoServiceImpl implements EchoService{
    @Override
    public String echo(String msg) {
        return "Echo:" + msg;
    }
}

需要注意的一点是,你需要在你的接口的实现类上加上@RpcService注解,让ok-rpc知道这是一个ok-rpc接口的实现类。至于
具体的接口,你需要添加在注解的参数中。

最后一步,当然是使用Spring的xml文件来主持bean了:


  <bean id="nodeList" class="io.hujian.npc.pubisher.RpcNodeGroup">
        <property name="nodeGroupName" value="test-node-list-group"/>
        <property name="nodeList" value="127.0.0.1:18999:1"/>
    </bean>
    
      <bean id="echoService" class="io.hujian.npc.pubisher.RpcServicePublishBean">
        <property name="nodeGroup" ref="nodeList"/>
        <property name="interfaceName" value="EchoService"/>
        <property name="url" value="io.hujian.rpc.test.client.EchoService"/>
        <property name="version" value="1.0.0"/>
    </bean>  

不要以为nodeList取名叫List就可以使用多个地址,目前来说完全只支持一个地址,上文已经说了ok-rpc的设计考虑。经过这几步,现在
你可以加载这个xml文件来启动你的rpc-server了,启动rpc-server也使用了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:component-scan base-package="io.hujian.*"/>

    <!-- load config file -->
    <bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:zkConfig.properties</value>
            </list>
        </property>
    </bean>

    <!-- The Rpc Discover Service -->
    <bean id="serviceDiscovery" class="io.hujian.npc.discover.ServiceDiscover"/>

    <bean id="rpcClient" class="io.hujian.npc.manager.RpcClient">
        <constructor-arg name="discover" ref="serviceDiscovery"/>
    </bean>

    <bean id="serviceRegistry" class="io.hujian.npc.register.SampleServiceRegister"/>

    <bean id="rpcServer" class="io.hujian.npc.manager.RpcServer"/>

</beans>

使用Spring加载上述文件即可启动ok-rpcserver,比如这个文件叫ApplicationContext.xml,则可以使用下面的代码
来启动ok-rpc服务器:

        new ClassPathXmlApplicationContext("ApplicationContext.xml");

  1. 客户端注册服务bean

首先,你需要有一份服务端提供的接口类文件,比如,你想要访问上面注册的EchoService,那么你就需要有一个这样的接口类。然后
你通过注册下面的bean来加载引用:


    <bean id="echoService" class="io.hujian.npc.consumer.RpcServiceReferenceBean"
          init-method="init">
        <property name="clazz" value="io.hujian.rpc.test.client.EchoService"/>
    </bean>

然后,你就可以使用这个bean了:


        ApplicationContext context = new ClassPathXmlApplicationContext("client-services.xml");
        EchoService echoService = (EchoService) context.getBean("echoService");

        System.out.println("Response:" + echoService.echo("hello, ok-rpc!"));

测试

Request 数量 Response数量 花费时间 qps 客户端使用线程数量
160000 160000 22473ms 7119 16
320000 320000 37836ms 8457 16
800000 800000 102226ms 7825 16

服务端运行时资源:

Server Load

客户端运行时资源:

Client Load

测试机器:MacBook Pro, 2.2GHz Intel Core i7 16GB 1600MHz DDR3

License


Copyright 2017 HuJian

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容