dubbo-filter 源码分析

说明:这个模块的功能是缓存调用结果,但是我有一个疑问,比如说开始调用的时候,返回结果列表中只有一条数据,另一个进程插入了一条数据,那么下一次调用缓存的那个方法时,那是返回一条结果,还是两条结果了?

Cache 接口定义了两个方法,put 和 get.

public interface Cache {
/**
* API to store value against a key
* @param key Unique identifier for the object being store.
* @param value Value getting store
*/
void put(Object key, Object value);

/**
 * API to return stored value using a key.
 * @param key Unique identifier for cache lookup
 * @return Return stored object against key
 */
Object get(Object key);

}

CacheFactory 定义了获取 Cache 的方法

@SPI(“lru”)
public interface CacheFactory {

/**
 * CacheFactory implementation class needs to implement this return underlying cache instance for method against
 * url and invocation.
 * @param url
 * @param invocation
 * @return Instance of Cache containing cached value against method url and invocation.
 */
@Adaptive("cache")
Cache getCache(URL url, Invocation invocation);

}

AbstractCacheFactory 实现了 CacheFactory 的基本骨架.

我们先看下 LruCache 吧,LruCache 是最近最久未使用,它的实现原理是借用了 LinkedHashMap 实现的.

public LruCache(URL url) {
final int max = url.getParameter(“cache.size”, 1000);
this.store = new LRUCache<>(max);
}

public class LruCacheFactory extends AbstractCacheFactory {

/**
 * Takes url as an method argument and return new instance of cache store implemented by LruCache.
 * @param url url of the method
 * @return ThreadLocalCache instance of cache
 */
@Override
protected Cache createCache(URL url) {
    return new LruCache(url);
}

}

ThreadLocalCache 是借助于 ThreadLocal 实现的.

JCache 是用于缓存的 Java API. 它提供一组通用的类和接口,可用于将 Java 对象临时存储在内存中. 所以即可以使用 JCache 实现,同样的,我也可以使用 Ecache 实现.

ExpiringMap 采用的 ConcurrentHashMap + Thread 实现可自动移除失效数据的结构,所以此处我认为采用 redis 实现效果会更好.

现在来重点关注下 CacheFilter 这个类. 这里实现了缓存结果的具体逻辑.

public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
if (cacheFactory != null && ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), CACHE_KEY))) {
Cache cache = cacheFactory.getCache(invoker.getUrl(), invocation);
if (cache != null) {
String key = StringUtils.toArgumentString(invocation.getArguments());
Object value = cache.get(key);
if (value != null) {
if (value instanceof ValueWrapper) {
return AsyncRpcResult.newDefaultAsyncResult(((ValueWrapper) value).get(), invocation);
} else {
return AsyncRpcResult.newDefaultAsyncResult(value, invocation);
}
}
Result result = invoker.invoke(invocation);
if (!result.hasException()) {
cache.put(key, new ValueWrapper(result.getValue()));
}
return result;
}
}
return invoker.invoke(invocation);
}

dubbo-filter-validation 包

Validator 类的实例在实际方法调用前对方法输入参数执行验证的扩展.
public interface Validator {

void validate(String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Exception;

}

Validation 获取 Validator 的工厂接口
@SPI(“jvalidation”)
public interface Validation {

/**
 * Return the instance of {@link Validator} for a given url.
 * @param url Invocation url
 * @return Instance of {@link Validator}
 */
@Adaptive(VALIDATION_KEY)
Validator getValidator(URL url);

}

AbstractValidation 抽象类,实现 Validation 的基本骨架.

ValidationFilter 在实际调用方法前,通过 Validation 校验参数的合法性(这个类似于以前在前端使用的 validateEngine 一样,通用的数据校验API).

public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
if (validation != null && !invocation.getMethodName().startsWith("$")
&& ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), VALIDATION_KEY))) {
try {
Validator validator = validation.getValidator(invoker.getUrl());
if (validator != null) {
validator.validate(invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
}
} catch (RpcException e) {
throw e;
} catch (Throwable t) {
return AsyncRpcResult.newDefaultAsyncResult(t, invocation);
}
}
return invoker.invoke(invocation);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
dubbo-py 是一个 Python 实现的 Dubbo 协议的客户端,它提供了简单易用的 API 以方便开发者在 Python 项目中使用 Dubbodubbo-py 的源代码托管在 GitHub 上,可以方便地查看和下载。 dubbo-py 的源码结构清晰,主要分为 dubbo_client 和 dubbo_codec 两个模块,其中 dubbo_client 模块实现了 Dubbo 协议的客户端,dubbo_codec 模块实现了 Dubbo 协议的序列化和反序列化操作。 在 dubbo_client 模块中,主要实现了 DubboClient 类和 DubboService 类。DubboClient 类封装了 Dubbo 协议的请求响应过程,提供 give_me_a_stub() 方法用于生成 DubboService 代理类。DubboService 类则是 Dubbo 服务实现类的代理类,使用时只需实例化 DubboService 类并调用其中的方法即可。DubboClient 和 DubboService 类的代码结构清晰,易于理解和调试。 在 dubbo_codec 模块中,主要实现了 Dubbo 协议的序列化和反序列化操作。DubboCodec 类实现了将 Python 对象转化成 Dubbo 协议要求的二进制数据,并提供了将 Dubbo 协议二进制数据转化成 Python 对象的方法。DubboCodec 类的实现较为复杂,但是提供了丰富的功能和对 Dubbo 协议的完整支持。 综上所述,dubbo-py 的源码结构清晰,实现简单易用,对 Dubbo 协议的支持非常完整。在 Python 项目中使用 Dubbo 的开发者可以通过查看 dubbo-py 的源码,学习 Dubbo 客户端的实现方法和 Dubbo 协议的序列化和反序列化操作,提高自己的技术水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值