4.2.2 大型网站技术和java中间件-服务框架 : 服务框架的设计和实现 : 透过示例看服务框架原型

本文深入探讨了Java RMI(Remote Method Invocation)在单机方式下的远程调用机制,包括服务框架的设计和实现过程,通过示例展示了如何在客户端和服务器端进行远程方法调用,并详细解析了关键步骤及背后的原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.2.2 大型网站技术和java中间件-服务框架 :  服务框架的设计和实现 : 透过示例看服务框架原型

示例:单机方式

//单机方式情况下:只需要直接调用
class RMIIUserImpl  {



    public String getUserName(int id)  {

        log.info("{}{}", getClass(), "正在远程调用");

        return "lmy86263";

    }



    public int getUserCount()   {

        return 1;

    }



    public User getUserByName(String name)    {

        return new User("lmy86263", 1);

    }

}

 

 

 

实例:远程调用:

 

//客户端实现:

public String getUserName(int id) {

    //获得可用的server的list

    List<String> serverList = getAvailableServerAddress("demo2.InterfaceOutRMI.getUserName");

    //确认要调用的server address

    String address = chooseTarget(serverList);

    //建立连接

    Socket socket = new Socket(address);

    //请求序列化

    byte[] request = genRequest(id);

    //发送请求

    socket.getOutputStream().write(request);

    //接收结果

    byte[] response = new byte[1024];

    socket.getInputStream().read(response);

    //解析结果

    String result = getResult(response);

    return result;

}

分析:

//获得可用的server的list

List<String> serverList = getAvailableServerAddress("demo2.InterfaceOutRMI.getUserName”);

 

1.getAvailableServerAddress 是根据服务名称来获取服务去机器的地址

   1.1 如果请求和服务中间有负载均衡器,获取的就是负载均衡器的地址

   1.2 如果使用名称服务器的方式,返回的就是可用的服务地址

2.参数  demo2.InterfaceOutRMI.getUserName

   2.1 参数是用来告诉名称服务器,要找哪个服务

   2.2 一般是使用全限定名加上版本来作为定位的key     

 

//确认要调用的server address

//从可用server中选取一个(在此过程中,完成负载均衡)

String address = chooseTarget(serverList);


服务端实现:


class SeverHandler {

    class Request {

        public Socket socket; //调用的连接

        public String serverName;//服务名称

        public String serverVersion;//服务版本

        public String methodName;//方法名称

        public Object[] args;//方法的参数

    }

    public static void deal() {

        while (true) {

            //获取客户端请求数据

            byte[] requestData = receiveRequest();

            //根据请求数据->解析为请求的request

            Request request = getRequest(requestData);

            //根据请求的信息,获取调用的对象,定位本地的服务地址

            Object service = getServiceByNameAndVersion(request);

            //根据对象,请求的方法名称和参数来调用函数并返回结果

            Object result = callSevice(service,request.methodName,request.args);

            //把返回的结果转换成字节码

            byte[] data = getResult(result);

            //执行结果返回给客户端

            request.socket.getOutputStream().write(data);

        }

    }

}

解析:

   1. while (true) {//需求持续的监听请求并处理

   2. Object service = getServiceByNameAndVersion(request);

      2.1 用来定位本地的服务地址

      2.2 实际上,会有服务注册表

          2.2.1 根据名称和版本号进行管理,

          2.2.2 启动时构建初始值,运行时提供修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值