zoukankan      html  css  js  c++  java
  • spring boot和thrift、zookeeper建立微服务

    原文地址:http://www.cnblogs.com/skyblog/p/5535418.html

        Spring cloud适应于云端服务,也适用于企业信息化SOA建设。spring boot也是restful微服务开发的利器。但对于内网服务,即服务与服务之间的调用,spring并没有去刻意封装,也许他们认为已经没有必要了,因为已经有了thrift、ice等强大的框架。

        如果是用spring boot本身提供的restful服务作为服务与服务之间的调用,效率低很多,thrift的效率大概是restful的100-1000倍左右。本篇既是基于spring boot框架,结合thrift和zookeeper实现的一个简单微服务框架,服务与服务之间使用thrift通信(thrift既是通信方式也是数据压缩方式)。

        本demo一共包括三个工程:

        cloud-thrift-server:服务提供方

        cloud-thrift-interface:接口及传输对象定义

        cloud-thrift-client:服务调用方

        开源代码地址:http://git.oschina.net/zhou666/spring-cloud-7simple

    1)建立thrift接口定义文档

        namespace java cloud.simple.service

        struct UserDto {

          1: i32 id

          2: string username

        }

         service UserService {

          UserDto getUser()

        }

        接口定义完后,使用thrift命令生成对应的java文件,主要生成两个文件,分别是UserService.java和UserDto.java,把这两个文件放入cloud-thrift-interface工程,因为客户端也需要这个接口定义。

    2)实现thrift服务注册

        在服务的提供端需要实现接口,并且还要把实现类注册到thrift服务器。

        UserService.Processor processor = new UserService.Processor(
    
                           new UserServiceImpl());
    
             TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(
    
                           tServerTransport()).processor(processor));

        UserServiceImpl就是接口实现类,将其注册金Tserver。

        注册完服务后,需要启动Tserver,很显然这个需要在线程里启动。

        executor.execute(new Runnable() {
    
                    @Override
    
                    public void run() {
    
                           tServer().serve(); 
    
                    }
    
        });

    3) 使用zookeeper进行服务名称注册

        上面是注册具体的服务执行类,这一步是将服务的实例注册进zookeeper,这样才能实现负载均衡。让客户端可以根据服务实例列表选择服务来执行。当然这里只需要注册服务所在服务器的IP即可,因为客户端只要知道IP,也就知道访问那个IP下的该服务。

       

    String servicePath = "/"+serviceName ;// 根节点路径
    
           ZkClient zkClient = new ZkClient(serverList);
    
           boolean rootExists = zkClient.exists(servicePath);
    
           if (!rootExists) {
    
               zkClient.createPersistent(servicePath);
    
           }
    
           InetAddress addr = null;
    
           try {
    
               addr = InetAddress.getLocalHost();
    
           } catch (UnknownHostException e) {
    
               e.printStackTrace();
    
           }
    
           String ip = addr.getHostAddress().toString();
    
           String serviceInstance = System.nanoTime() +"-"+ ip;
    
           // 注册当前服务
    
           zkClient.createEphemeral(servicePath + "/" + serviceInstance);
    
           System.out.println("提供的服务为:" + servicePath + "/" + serviceInstance);

        要注意这里使用zkClient.createEphemeral建立临时节点,如果这台服务器宕机,这个临时节点是会被清除的,这样客户端在访问时就不会再选择该服务器上的服务。

    4) 客户端更新服务列表

        客户端需要能及时的监听服务列表的变化并作出负载均衡,我们用如下方式监听服务列表的变化:

      

     // 注册事件监听
    
             zkClient.subscribeChildChanges(servicePath, new IZkChildListener() {
    
                    // @Override
    
                    public void handleChildChange(String parentPath,
    
                                  List<String> currentChilds) throws Exception {
    
                           // 实例(path)列表:当某个服务实例宕机,实例列表内会减去该实例
    
                           for (String instanceName : currentChilds) {
    
                                  // 没有该服务,建立该服务
    
                                  if (!serviceMap.containsKey(instanceName)) {
    
                                         serviceMap.put(instanceName,createUserService(instanceName));
    
                                  }
    
                           }
    
                           for (Map.Entry<String, UserService.Client> entry : serviceMap.entrySet()) {
    
                                  // 该服务已被移除
    
                                  if (!currentChilds.contains(entry.getKey())) {
    
                                         serviceMap.remove(entry.getKey());
    
                                  }
    
                           }
    
                           System.out.println(parentPath + "事件触发");
    
                    }
    
        });

        有了服务列表,客户端在调用服务的时候就可以采用负载均衡的方式了,在这里使用最简单的随机方式:

          

      public UserService.Client getBalanceUserService(){       
    
             Map<String, UserService.Client> serviceMap =ZooKeeperConfig.serviceMap;
    
             //以负载均衡的方式获取服务实例           
    
             for (Map.Entry<String, UserService.Client> entry : serviceMap.entrySet()) {
    
                    System.out.println("可供选择服务:"+entry.getKey());
    
             }
    
             int rand=new Random().nextInt(serviceMap.size());           
    
             String[] mkeys = serviceMap.keySet().toArray(new String[serviceMap.size()]);
    
             return serviceMap.get(mkeys[rand]);
    
      }

    本文结束,具体参见代码,另外,之前还不了解thrift和zookeeper的朋友,不要被他们吓到,其实他们是很轻量级的技术,很容易上手,这也许就是他们流行的原因。

  • 相关阅读:
    NX二次开发-创建直线(起点-向量方向-长度)UF_CURVE_create_line
    NX二次开发-创建圆弧(圆心-半径)UF_CURVE_create_arc
    NX二次开发-UFUN获取直线的两个端点UF_CURVE_ask_line_data
    NX-二次开发创建圆弧(三点圆弧)UF_CURVE_create_arc_3point
    NX二次开发-创建直线UF_CURVE_create_line与NXOpen->CreateLine
    NX二次开发-创建圆弧(起点-终点-半径)UF_CURVE_create_arc_point_point_radius
    NX二次开发-UFUN打开信息窗口UF_UI_open_listing_window()
    NX二次开发-UFUN信息窗口打印UF_UI_write_listing_window
    NX二次开发-UFUN单按钮模态对话框窗口打印uc1601用法
    NX二次开发-UFUN打开二进制STL文件函数UF_STD_open_binary_stl_file
  • 原文地址:https://www.cnblogs.com/boonya/p/7462436.html
Copyright © 2011-2022 走看看