Gude Blog


  • 首页

  • 关于

  • 归档

  • 标签

学习dubbo源码-消费者服务调用

发表于 2018-05-28
1
2
DemoService demoService = (DemoService) context.getBean("demoService");
demoService.sayHello("world");

由上一节分析知道调用demoService实际上是返回的proxy0(不一定是0)代理类,由于proxy0源码没有,所以debug会直接进InvokerInvocationHandler

InvokerInvocationHandler.invoke:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class InvokerInvocationHandler implements InvocationHandler {

private final Invoker<?> invoker;

public InvokerInvocationHandler(Invoker<?> handler) {
this.invoker = handler;
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//proxy=proxy0 代理类本身 method:调用方法 args:方法参数
String methodName = method.getName();
Class<?>[] parameterTypes = method.getParameterTypes();
if (method.getDeclaringClass() == Object.class) {
return method.invoke(invoker, args);
}
if ("toString".equals(methodName) && parameterTypes.length == 0) {
return invoker.toString();
}
if ("hashCode".equals(methodName) && parameterTypes.length == 0) {
return invoker.hashCode();
}
if ("equals".equals(methodName) && parameterTypes.length == 1) {
return invoker.equals(args[0]);
}
//invoker=MockClusterInvoker
return invoker.invoke(new RpcInvocation(method, args)).recreate();
}

}

阅读全文 »

学习dubbo源码-服务引用

发表于 2018-05-26
1
<dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService" timeout="60000" version="10.11.11" group="guodong"/>

入口

DubboNamespaceHandler配置了自定义dubbo标签的解析。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class DubboNamespaceHandler extends NamespaceHandlerSupport {

static {
Version.checkDuplicate(DubboNamespaceHandler.class);
}

public void init() {
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
}

}

DubboBeanDefinitionParser会对标签进行解析,并把相关参数设置到RootBeanDefinition,并返回它。RootBeanDefinition有个很关键的方法setBeanClass,这里设置的beanClass为ReferenceBean。

ReferenceBean实现了FactoryBean,其返回的Bean对象不是指定类的一个实例,而是该FactoryBean的getObject方法所返回的对象。
ReferenceBean的getObject方法会调用ReferenceConfig的get()方法。

1
2
3
4
5
6
7
8
9
10
11
public class ReferenceConfig<T> extends AbstractReferenceConfig{
public synchronized T get() {
if (destroyed){
throw new IllegalStateException("Already destroyed!");
}
if (ref == null) {
init();
}
return ref;
}
}

核心就是init(),它会对配置进行检测并创建代理 createProxy(map);

阅读全文 »

学习dubbo源码-远程暴露

发表于 2018-04-15

远程暴露


1 获取Invoker,本地暴露差不多, 然后通过protocol.export(wrapperInvoker)暴露服务

阅读全文 »

fastsoso被攻击,限制访问频次

发表于 2018-04-14

fastsoso最近被大量ip攻击,单核的服务器实在承受不起,最近想要给他加个拦截,对于每分钟访问数超过一定阈值的ip,直接进行拦截!

阅读全文 »

学习dubbo源码-本地暴露

发表于 2018-04-07

本地暴露


1 主要目的是获取exporter

阅读全文 »

学习dubbo源码-服务暴露原理

发表于 2018-04-05


服务提供者暴露一个服务的详细过程


暴露服务时序

阅读全文 »

学习dubbo源码-Compile动态编译

发表于 2018-02-19

Compiler是一个SPI扩展点,他实现有

1
2
3
adaptive=com.alibaba.dubbo.common.compiler.support.AdaptiveCompiler
jdk=com.alibaba.dubbo.common.compiler.support.JdkCompiler
javassist=com.alibaba.dubbo.common.compiler.support.JavassistCompiler

默认实现是javassist

javassist

Javassist是一个开源的分析、编辑和创建Java字节码的类库,它可以使我们对于字节码的操作变的更加的简单。

阅读全文 »

学习dubbo源码-SPI扩展点

发表于 2018-02-18

从网上了解到要学习dubbo的源码,必须要从SPI开始,dubbo框架作者从设计之初,就作为一个高可扩的服务框架。

java SPI

全称(Service Provider Interface),主要作用是提供接口,不同厂商对接口可以有自己不同的实现。我们比较熟悉的就是java.sql.Driver接口。
当厂商提供实现之后,需要在classpath:META-INF/services/下创建服务接口名的文件,并把具体的实现类写进去。
MySql驱动mysql-connector-java中,META-INF/services/文件中就有一个java.sql.Driver文件,内容是:

1
2
com.mysql.jdbc.Driver
com.mysql.fabric.jdbc.FabricMySQLDriver

我们可以通过如下加载扩展点

1
2
3
4
5
ServiceLoader<接口> serviceLoader=ServiceLoader.load(接口.class); 

for(接口 cmd:serviceLoader){
cmd.method();
}

官方文档对ServiceLoader类的功能介绍

阅读全文 »

jdk常用命令

发表于 2017-12-24

进程的本地虚拟机唯一ID(LVMID),LVMID与操作系统的进程ID(PID)是一致的。

jps

显示所有HotSpot虚拟机进程

  1. jps 显示类名
  2. jps -l 显示主类的全名
  3. jps -v 输出进程启动的JVM参数
阅读全文 »

数据库连接池连接复用原理

发表于 2017-12-16

HikariCP的ProxyConnection类有如下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// **********************************************************************
// "Overridden" java.sql.Connection Methods
// **********************************************************************

/** {@inheritDoc} */
@Override
public final void close() throws SQLException
{
// Closing statements can cause connection eviction, so this must run before the conditional below
closeStatements();

if (delegate != ClosedConnection.CLOSED_CONNECTION) {
leakTask.cancel();

try {
if (isCommitStateDirty && !isAutoCommit) {
delegate.rollback();
lastAccess = currentTime();
LOGGER.debug("{} - Executed rollback on connection {} due to dirty commit state on close().", poolEntry.getPoolName(), delegate);
}

if (dirtyBits != 0) {
// 重置catalog、schema、sReadOnly、AutoCommit、transactionIsolation、NetworkTimeout这些属性
poolEntry.resetConnectionState(this, dirtyBits);
lastAccess = currentTime();
}

delegate.clearWarnings();
}
catch (SQLException e) {
// when connections are aborted, exceptions are often thrown that should not reach the application
if (!poolEntry.isMarkedEvicted()) {
throw checkException(e);
}
}
finally {
delegate = ClosedConnection.CLOSED_CONNECTION;
//PoolEntry会被设为STATE_NOT_IN_USE,PoolEntry保存了Connection
poolEntry.recycle(lastAccess);
}
}
}

从上代码可知,ProxyConnection重写了Connection的Close方法,在我们结合spring调用完如数据库查询会调用connection.close(),但是ProxyConnection并不会真正去关闭连接,而是重置该连接的状态,使得该连接可以继续被使用。

123…7
Gude

Gude

Stay Hungry. Stay Foolish.

64 日志
27 标签
GitHub
© 2019 Gude   |  Google网站地图   |  百度网站地图   |  Hosted by Coding Pages
由 Hexo 强力驱动
主题 - NexT.Pisces
  |  本站总访问量次   |  您是第 位访客