GithubHelp home page GithubHelp logo

nsrpc's Introduction

ok-rpc

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

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

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

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

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

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来加载引用,ok-rpc支持同步和异步调用,下面是详细示例:

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

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

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

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

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

        HelloService helloService = (HelloService) context.getBean("syncHelloService");

        System.out.println("Sync Call Result:" + helloService.hello("hello ok-rpc"));

        IAsyncObjectProxy proxy = (IAsyncObjectProxy) context.getBean("futureHelloService");

        RPCFuture future = proxy.call("hello", "hello ok-rpc");

        try {
            System.out.println("Future Call Type:" + future.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        proxy = (IAsyncObjectProxy) context.getBean("callbackHelloService");

        proxy.call("hello", "hello ok-rpc").addCallback(new AsyncRPCCallback() {
            @Override
            public void success(Object result) {
                System.out.println("Callback Call Result:" + result);
            }

            @Override
            public void fail(Exception e) {
                System.out.println("Callback Call Result:" + e);
            }
        });

测试

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

服务端运行时资源:

服务端

客户端运行时资源:

客户端

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

Checklist & Todolist

   1、性能优化,提升qps
   2、添加服务暴露时的版本控制,可提供多个版本的统服务
   3、服务端-客户端协议重新设计
   4、更多的编解码器设计
   5、代码格式调整、组织结构调整
   6bug检测、修复
   7、服务详情统计上报
   8、服务降级
   9、配置内容迁移到配置文件中加载,而不是写死在代码中(也别使用Constant类了吧!)
   10、负载均衡合理、合法化(BugFix)
   11、获取clientHandlerNULL时的轮询问题,希望可以做成首先将请求缓存起来,等可以获取到Client Handler的时候再尝试执行。或者
       调整架构,使得不会出现在请求到达之前client handler还没有就绪的情况 !!!

更新日志

[2017-10-06 11:03] 项目移动,initreadme 

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.

nsrpc's People

Contributors

pandening avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.