【Motan源码学习】5-心跳机制

Motan的心跳机制有两种,一种是Server(或者说服务发布者)发给注册中心的,一种是Client(或者说服务引用者)发给Server的。

Server HeartBeat to Registry

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public AbstractRegistry(URL url) {
this.registryUrl = url.createCopy();
MotanSwitcherUtil.registerSwitcherListener(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, new SwitcherListener() {
@Override
public void onValueChanged(String key, Boolean value) {
if (key != null && value != null) {
if (value) {
available(null);
} else {
unavailable(null);
}
}
}
});
}

在创建Registry的时候会为REGISTRY_HEARTBEAT_SWITCHER这个开关,注册一个监听器,当开关的值发生变更的时候,执行相应的操作。这个机制是为了实现Server的预览以及优雅停机,Server跟zk等注册中心建立链接后,服务是unreachable状态,此时并不会真正对外提供服务。可以在unreachable状态下进行预览,确认服务正常后,在打开心跳开关,正式提供服务。服务下线时也是先停止心跳变为unreachable状态,等确认没有client调用后就可以停止服务了。

【Motan源码学习】3-扩展机制

RPC 框架中有很多地方需要可扩展,比如,序列化(Thrift, Protocol Buffer, Hessian等),LoadBalance策略(随机、权重、Round Robin等),这些东西都要方便扩展且可以在配置文件中指定使用哪一种。
Motan 使用了一种 SPI (Service Provider Interface)的机制,实现上和阿里的 cooma 类似。本质上都是定义一个接口,该接口可以有很多实现,代码中面向接口编程,但具体使用哪个实现可以在配置文件中指定,然后用反射的机制去加载和使用它。只不过看实现的是否优雅。

400
motan-core 模块中的 META-INF/services 定义了一系列扩展点。文件名为接口名,文件内容为接口的实现类名, 可以配置多个实现类,每个类名占一行。

【Motan源码学习】2-与Spring集成

motan-core#com.weibo.api.motan.config 这个 package 定义了一系列 Config 类,用于处理服务发布和服务引用的一些配置。
关于Config, Motan 支持三种使用方式:

  • 编程 API
  • 与 Spring 集成的 XML 配置
  • 与 Spring 集成的 Annotation 配置
    我们先来看下编程 API 的使用方式,然后看看 Motan 是如何与 Spring 集成的,本文假设你已经对 Spring 的启动过程和一些 hook 接口有基本的了解。

编程 API

1. 服务发布

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ServiceConfig<MotanDemoService> motanDemoService = new ServiceConfig<MotanDemoService>();
// 设置接口及实现类
motanDemoService.setInterface(MotanDemoService.class);
motanDemoService.setRef(new MotanDemoServiceImpl());
// 配置服务的group以及版本号
motanDemoService.setGroup("motan-demo-rpc");
motanDemoService.setVersion("1.0");
// 配置ZooKeeper注册中心
RegistryConfig zookeeperRegistry = new RegistryConfig();
zookeeperRegistry.setRegProtocol("zookeeper");
zookeeperRegistry.setAddress("127.0.0.1:2181");
motanDemoService.setRegistry(zookeeperRegistry);
// 配置RPC协议
ProtocolConfig protocol = new ProtocolConfig();
protocol.setId("motan");
protocol.setName("motan");
motanDemoService.setProtocol(protocol);
motanDemoService.setExport("motan:8002");
// 服务发布
motanDemoService.export();

【Motan源码学习】1-总体架构

【Motan源码学习】系列,不搞大而虚的架构,还是会继续深入源码,剖析RPC框架的内幕,会尝试总结出一些好的系统设计,尝试带着问题去看源码。搞这个系列最主要的目的是驱动自己认真的读源码。虽然说不搞大而虚的架构,但脑子里还是需要一幅大图的. 看过 Tomcat 源码之后深有体会,刚开始掌握大概流程和整体架构,然后一步步深入,搞懂图中的每个组件。

简介

Motan 是微博研发并开源的 Java 的 RPC 框架,项目地址:https://github.com/weibocom/motan. 我将在 0.3.1 版本上开始源码的学习。(为什么你不去看 dubbo 呢?dubbo 虽然很屌,除了阿里,在国内很多其他互联网公司也都用它。然。。。我大概过了一遍两个项目,觉得 Motan 更小而美一点,可能看源码的门槛低一点吧)

【Tomcat学习笔记】15-Connector

Connector配置

Connector 属于 StandardService 里的一个组件,可以在 server.xml 中配置,指定协议、端口、超时时间等。

1
2
3
4
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
</Service>

每个 Service 里可以配置多个 Connector. Tomcat 的 Connector 支持两种协议,HTTP 和 AJP. 关于这两种协议,官方文档如此说:

  • The HTTP connector is setup by default with Tomcat, and is ready to use. This connector features the lowest latency and best overall performance.
  • When using a single server, the performance when using a native webserver in front of the Tomcat instance is most of the time significantly worse than a standalone Tomcat with its default HTTP connector, even if a large part of the web application is made of static files. If integration with the native webserver is needed for any reason, an AJP connector will provide faster performance than proxied HTTP. AJP clustering is the most efficient from the Tomcat perspective. It is otherwise functionally equivalent to HTTP clustering.

【Tomcat学习笔记】14-Cluster

Tomcat Cluster 这块代码较多,就不贴代码一步步看了,这里从更宏观的视角分析和总结一下。代码主要在 org.apache.catalina.ha 和 org.apache.catalina.tribes 两个package. ha这个package主要做了两件事,或者说Tomcat cluster 主要就做了这两件事:集群间 Session 同步 和 集群War部署。tribes 则是Tomcat 集群通讯模块。

【Tomcat学习笔记】13-Session

说明,为了简洁,这里贴的代码可能有所删减。

1. Session入门

网上会经常看到介绍Session和Cookie区别的文章,当年我也傻傻的看过,然这两个根本不是一个东西,有啥好比较的,简直就好比问TCP和JAVA的区别。

Session 是什么?我就不去抄维基百科了,谢晞鸣的理解:HTTP协议本身是无状态的(所谓无状态,就是指前后两HTTP请求是独立的,后面的HTTP请求没法知道前面那次做了啥),但在很多场景中,我们需要有状态,比如用户的登录态,而 Session 就是这样一种让应用有状态的机制。

Session 最简单的用法是:
【1】在登录方法中

1
2
3
4
5
Boolean isLogin = login(userId, password)
if(isLogin) {
HttpSession session = request.getSession();
session.setAttribute("userId", userId);
}