查看原文
其他

什么是小米生态云RPC框架?看完你就懂了!

RPC服务治理已经在小米生态云上线,这篇文章告诉你小米生态云的RPC的框架以及怎么样快速接入RPC服务。

先引入一个概念-Apus

Apus是小米工程团队为小米和生态链提供的服务化的RPC框架。该框架是基于Facebook Swift开发的分布式服务框架,实现高可扩展性的RPC调用同时提供了服务发现及服务治理能力,支持自定义注册中心、分组策略、负载路由策略,以及监控指标统计等功能。


Apus对标业界主流RPC框架,如Dubbo,Motan,Finagle和gRPC等。 业界 RPC 框架大致分为两类,一种是偏重服务治理,另一种侧重跨语言调用。 服务治理型的RPC框架典型的是Dubbo,Motan等,提供了强大的服务管理能力,缺点是需要使用特定语言编程,跨语言调用支持难度大; 跨语言调用的RPC框架典型的有Thrift,gRPC等,提供了跨语言调用支持,但服务管理能力较弱,没有服务发现和注册的模块。


Apus底层使用Thrift,支持不同语言通过Thrift协议调用,目前服务注册和治理已支持Java,多语言的SDK已在开发过程中。在此之上我们实现了服务治理中心,支持分组策略和负载路由策略,使之在支持跨语言调用的同时仍然具备强大的服务管理能力。小米的RPC框架已经在内部使用多年,经过小米众多业务千锤百炼,积累了大量实践,并且在大量实践的基础上,我们能提供更及时,更精准的技术支持。


除此之外,Apus还有极高的扩展性,比如Apus内置的监控模块支持了Open-Falcon,在金山云可以很方便的看到调用方法、次数和异常次数等监控指标:


◇client监控项


thriftcli-${ifaceClassName}-${methodName}:client 调用 methodname 方法的时间,次数


thriftcli-${ifaceClassName}-${methodName}_fail:methodname 调用失败次数


thriftcli-${ifaceClassName}exception-${exceptionName}:exceptionName 异常的调用次数



◇server监控项


method/${methodName}:methodName 调用次数,时间


method/ALL_THRIFT_METHODS:所有 method 调用次数,时间


method/${methodName}_fail:methodName 调用失败次数


exception/${exceptionName}: exception 次数 


method/ALL_THRIFT_METHODS_FAIL: 所有 method 调用失败次数


如果你想实现其他监控系统的集成,比如AWS的CloudWatch也非常简单,只需实现以下接口即可:


○ Metrics


public void count(Counter counter)


public void countDuration(Method method, long duration): 统计方法执行时间,次数


public void countException(Method method, Throwable throwable):统计异常次数


○ Counter


private String name:Counter name,表示统计的一个指标 Key


private long longValue:调用次数


private String tags:标签


private long time:执行时间
....


如何快速接入RPC

简单即是美,Apus使用起来非常简单。仅需三步就可以让一个服务端应用跑起来:


1.接口定义:


public class EchoServer {

  @ThriftService("EchoServer")    

  public interface Iface {

     @ThriftMethod("echo")      

   String echo(String input);

}

  // 异步接口,如果不需要可以不定义

  @ThriftService("EchoServer")

 public interface AsyncIface {

    @ThriftMethod("echo")        

    ListenableFuture<String> echo(String input);

} }


2.接口实现:


public class EchoServerImplimplementsEchoServer.Iface{    

  @Override

  public String echo(String input) {        

     return input;

  }

}


3.服务启动:


public class Server {    

   public static void main(String[] args) {                
        ServerConfig<EchoServerImpl>
config = new ServerConfig.Builder<>(EchoServerImpl.class)                        
           .registryFactory(
new ServiceCenterRegistryFactory(EchoServerImpl.class))                    
                 .port(12346).build();          

      Bootstrap<EchoServerImpl> bootstrap = new Bootstrap<>(config);

      bootstrap.start();

  }

}


如上,我们完成了一个简单的服务端应用。

接下来我们实现一个客户端对其进行调用,


public class Client {
   public static void main(String[] args) throws InterruptedException {
       // client 调用同步接口 String request = "Hello Xiaomi!";
       ClientConfig<EchoServer.Iface> syncClientConfig = new ClientConfig.ClientConfigBuilder<>(EchoServer.Iface.class) .registryFactory(new ZookeeperRegistryFactory(EchoServer.Iface.class)) .build();
EchoServer.Iface newSyncClient = new SwiftClientManager<>(syncClientConfig).createClient();
String response = newSyncClient.echo(request);
System.out.println(response);
// client 调用异步接口
String asyncRequest = "Hello Xiaomi!(async)";
ClientConfig<EchoServer.AsyncIface> asyncIfaceClientConfig = new ClientConfig.ClientConfigBuilder<>(EchoServer.AsyncIface.class) .registryFactory(new ZookeeperRegistryFactory(EchoServer.Iface.class)) .build();
EchoServer.AsyncIface newAsyncClinet = new SwiftClientManager<>(asyncIfaceClientConfig).createClient();
ListenableFuture<String> future = newAsyncClinet.echo(asyncRequest);
Futures.addCallback(future, new FutureCallback<String>() {
   @Override public void onSuccess(String result) {
       System.out.println(result); }
   @Override public void onFailure(Throwable t) { t.printStackTrace(); } });
  Thread.sleep(1000); }
}


如上所示,我们完成了构建一个完整的简单服务的所有工作,更多详细文档请戳左下方“阅读原文”。

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存