从零学习Hession RPC

为什么学习Hessian RPC?

  • 存粹的RPC,只解决PRC的四个核心问题(1.网络通信2.协议 3.序列化 4.代理)
  • Java写的
  • HessianRPC落伍了,但是它的序列化方式还保存着,被Dubbo(Hessian Lite)使用。
    被落伍,只是因为Hessian RPC出的比较早,当时没有注册中心,熔断,限流等。所以当我们学习PRC时,最好学一个简单的,存粹的,没有其他的额外功能。

Hessian 的概念

Hession 是Resin服务器的伴生产品。基于Java编程语言设计的RPC框架,只支持Java编程语言使用,现在新出的gRPC Thrift,支持多语言。Hessian的序列化是二进制的。

Hessian设计思想

Hessian使用的resin服务器,类似于Tomcat,使用的是HTTP协议,由于使用的是JDK做代理,所以必须要用接口定义调用类。对象的数据类型,必须要实现Serliazble。服务的发布需要使用HessanServlet进行配置,在web.xml进行配置。
那么如何进行调用配置的服务,客户端进行代理,HessianProxyFactory做代理服务。
从零学习Hession RPC_第1张图片

RPC的开发

引入依赖

<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.32</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.9</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>

        <dependency>
            <groupId>com.caucho</groupId>
            <artifactId>hessian</artifactId>
            <version>4.0.38</version>
        </dependency>
</dependencies>

开发服务端

1. 开发Service
2. DAO --- Mybaits
注意:一定要定义Service的接口,自定义的数据类型实现Serliazliable

模拟一下登录功能:
实体类

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private String password;
}

Service

public interface UserService {
    public boolean login(String username,String password);

    public void register(User user);

}

ServrceImpl

@Slf4j
public class UserServiceImpl implements UserService {
    @Override
    public boolean login(String username, String password) {
        log.debug("login method invoke name {} password {}",username,password);
        return false;
    }

    @Override
    public void register(User user) {
        log.debug("register method invoke user {}",user);
    }
}

配置web.xml

 <servlet>
        <servlet-name>userServiceRPCservlet-name>
        <servlet-class>com.caucho.hessian.server.HessianServletservlet-class>
        <init-param>
            <param-name>home-apiparam-name>
            <param-value>com.liu.service.UserServiceparam-value>
        init-param>
        <init-param>
            <param-name>home-classparam-name>
            <param-value>com.liu.service.UserServiceImplparam-value>
        init-param>
    servlet>
    <servlet-mapping>
        <servlet-name>userServiceRPCservlet-name>
        <url-pattern>/userServiceRPCurl-pattern>
    servlet-mapping>

客户端开发

@Slf4j
public class HessianRPCClient {
    public static void main(String[] args) throws MalformedURLException {
        // TODO
        HessianProxyFactory factory = new HessianProxyFactory();

        String urlName = "http://localhost:8080/rpc_hessian/userServiceRPC";
        UserService userService = (UserService) factory.create(UserService.class, urlName);
        boolean login = userService.login("liu", "123456");
        log.debug("userService value is {}",login);

    }
}

HessianRPC核心源码分析

1. HessianRPC client创建代理的方式 JDK Proxy.newProxyInstance()
   public Object create(Class<?> api, URL url, ClassLoader loader){
    if (api == null)
      throw new NullPointerException("api must not be null for HessianProxyFactory.create()");
    InvocationHandler handler = null;

    handler = new HessianProxy(url, this, api);

    return Proxy.newProxyInstance(loader,
                                  new Class[] { api,
                                                HessianRemoteObject.class },
                                  handler);
  }

2. 代理中   
     通过网络 Http请求 连接 远端RPC服务
     通过流 数据写出去了。
   HessianProxy#invoke()  
     1.通过 URLConnection 进行网络连接 
     2.解析协议 传递数据

Hessian序列化

前面说了,Hessian已经落伍了,但他的序列化方式还保留着,我们看看怎么使用的。

  // 1. 序列化
        OutputStream  outputStream = new FileOutputStream("D:\\StudyCodes\\rpc_lession\\rpc_hessian\\test");
        Hessian2Output hessian2Output = new Hessian2Output(outputStream);
        hessian2Output.writeObject(new User("liu", "123456"));
        hessian2Output.flush();
        outputStream.close();
        // 2. 反序列化
        InputStream inputStream = new FileInputStream("D:\\StudyCodes\\rpc_lession\\rpc_hessian\\test");
        Hessian2Input hessian2Input = new Hessian2Input(inputStream);
        User user = (User) hessian2Input.readObject();
        System.out.println(user);
        inputStream.close();
        log.info("user: {}", user);

你可能感兴趣的:(学习,rpc,网络协议)