既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
### 服务消费端调用流程
#### 1. InvokerInvocationHandler#invoke
* 拦截定义在 Object 类中的方法(未被子类重写),比如 wait/notify
* 判断方法名是否为toString, 是直接调用toString方法, 不需要远程调用
* 判断方法名是否为hashCode, 是直接调用hashCode方法 不需要远程调用
* 判断方法名是否为equals, 是直接调用equals方法; 不需要远程调用
* 都不是,invoker.invoke(new RpcInvocation(method, args))发起远程调用;
public class InvokerInvocationHandler implements InvocationHandler {
private static final Logger logger = LoggerFactory.getLogger(InvokerInvocationHandler.class);
private final Invoker<?> invoker;
public InvokerInvocationHandler(Invoker<?> handler) {
this.invoker = handler;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
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]);
}
// 这里的recreate方法很重要,他会调用AppResponse的recreate方法,
// 如果AppResponse对象中存在exception信息,则此方法中会throw这个异常
return invoker.invoke(new RpcInvocation(method, args)).recreate();
}
}
##### RpcInvocation
该类的属性包含服务调用的参数;
* returnType 设置返回值的类型
* methodName : 调用的方法名;
* parameterTypes : 方法参数类型;
* arguments : 参数值
* invoker : 为空,没有传递;
* attachments : 服务配置的一些相关信息,超时等;
public class RpcInvocation implements Invocation, Serializable {
public RpcInvocation(Method method, Object[] arguments, Map<String, String> attachment) {
this(method.getName(), method.getParameterTypes(), arguments, attachment, null);
//设置返回值的类型;
this.returnType = method.getReturnType();
}
public RpcInvocation(String methodName, Class<?>[] parameterTypes, Object[] arguments, Map<String, String> attachments, Invoker<?> invoker) {
this.methodName = methodName;
this.parameterTypes = parameterTypes == null ? new Class<?>[0] : parameterTypes;
this.arguments = arguments == null ? new Object[0] : arguments;
this.attachments = attachments == null ? new HashMap<String, String>() : attachments;
this.invoker = invoker;
}
}
因此, 服务端执行服务的时候, RpcInvocation实例包含了服务执行需要的数据;
#### 2. MockClusterInvoker#invoke
InvokerInvocationHandler#invoke中, invoker属性类型为MockClusterInvoker实例;执行一些Mock逻辑;
1. 判断mock配置是否为空,为空,则不执行mock逻辑, 调用下一个Invoker的invoke方法;
2. 不为空, 且是force开头, 调用Mock逻辑doMockInvoke方法,结束远程调用;
public class MockClusterInvoker implements Invoker {
private final Directory directory;
private final Invoker invoker;
@Override
public Result invoke(Invocation invocation) throws RpcException {
Result result = null;
String value = directory.getUrl().getMethodParameter(invocation.getMethodName(), MOCK_KEY, Boolean.FALSE.toString()).trim();
if (value.length() == 0 || "false".equalsIgnoreCase(value)) {
//no mock
result = this.invoker.invoke(invocation);
} else if (value.startsWith("force")) {
//force:direct mock 强制调用Mock逻辑, 直接放回数据;
result = doMockInvoke(invocation, null);
} else {
//省略部分代码
}
return result;
}
}
#### 3.1 AbstractClusterInvoker#invoke
接下来是集群容错功能的Invoker, 默认的FailoverClusterInvoker内部没有定义invoke方法,其继承了AbstractClusterInvoker类中定义了invoke方法, 因此调用的是父类的invoke方法;
干了三件事:
1. 获取RpcContext中的attachments设置给RpcInvocation对象;
2. 调用list方法 ,调用路由链从服务目录上,获取合适的Invoker实例invokers ;
3. 初始化并获取负载均衡策略loadbalance;
4. 调用子类FailoverClusterInvoker实现的方法doIoke
@Override
public Result invoke(final Invocation invocation) throws RpcException {
checkWhetherDestroyed();
// binding attachments into invocation.
Map<String, String> contextAttachments = RpcContext.getContext().getAttachments();
if (contextAttachments != null && contextAttachments.size() != 0) {
((RpcInvocation) invocation).addAttachments(contextAttachments);
}
List<Invoker<T>> invokers = list(invocation);
LoadBalance loadbalance = initLoadBalance(invokers, invocation);
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
return doInvoke(invocation, invokers, loadbalance);
}
#### 3.2 FailoverClusterInvoker#doInvoke
* 根据负载均衡策略,选出一个Invoker执行;
* 第一次正常调用,调用失败,会重试两次, 共调用3次;
工作流程:
1. 获取methodName;
2. 获取重试次数, 默认值为2; 会进行+1操作, 因此需要把第一次调用算进去;
3. 调用select方法, 负载均衡选出一个服务;
4. 调用下一个invoker#invoke方法;
public class FailoverClusterInvoker extends AbstractClusterInvoker {
public FailoverClusterInvoker(Directory directory) {
super(directory);
}
@Override
@SuppressWarnings({“unchecked”, “rawtypes”})
public Result doInvoke(Invocation invocation, final List<Invoker> invokers, LoadBalance loadbalance) throws RpcException {
List<Invoker> copyInvokers = invokers;
String methodName = RpcUtils.getMethodName(invocation);
int len = getUrl().getMethodParameter(methodName, RETRIES_KEY, DEFAULT_RETRIES) + 1;
if (len <= 0) {
len = 1;
}
// retry loop.
RpcException le = null; // last exception.
List<Invoker> invoked = new ArrayList<Invoker>(copyInvokers.size()); // invoked invokers.
Set providers = new HashSet(len);
for (int i = 0; i < len; i++) {
if (i > 0) {
checkWhetherDestroyed();
copyInvokers = list(invocation);
// check again
checkInvokers(copyInvokers, invocation);
}
Invoker invoker = select(loadbalance, invocation, copyInvokers, invoked);
invoked.add(invoker);
RpcContext.getContext().setInvokers((List) invoked);
try {
Result result = invoker.invoke(invocation);
//省略部分代码
return result;
} catch (RpcException e) {
} catch (Throwable e) {
le = new RpcException(e.getMessage(), e);
} finally {
providers.add(invoker.getUrl().getAddress());
}
}
//异常处理
}
}
下一个Invoker的类型为RegistryDirectory$InvokerDelegate类, 调用InvokerDelegate#invoke方法
#### 4 InvokerDelegate#invoke
InvokerDelegate类没有定义invoke方法, 其继承了InvokerWrapper,其定义了invoke方法;
这个代理对象invoke,啥都没干;
private static class InvokerDelegate extends InvokerWrapper {
private URL providerUrl;
public InvokerDelegate(Invoker<T> invoker, URL url, URL providerUrl) {
super(invoker, url);
this.providerUrl = providerUrl;
}
public URL getProviderUrl() {
return providerUrl;
}
}
public class InvokerWrapper implements Invoker {
private final Invoker<T> invoker;
@Override
public Result invoke(Invocation invocation) throws RpcException {
return invoker.invoke(invocation);
}
}
#### 5 CallbackRegistrationInvoker#invoke
* ProtocolFilterWrapper生成的Invoker;
* 会调用执行过滤器链, 执行完执行完得到结果;
* 拿到结果后,会获取ListenableFilter中的listener,执行listener的onResponse方法
static class CallbackRegistrationInvoker<T> implements Invoker<T> {
private final Invoker<T> filterInvoker;
private final List<Filter> filters;
@Override
public Result invoke(Invocation invocation) throws RpcException {
// 执行过滤器链
Result asyncResult = filterInvoker.invoke(invocation);
// 过滤器都执行完了之后,回调每个过滤器的onResponse或onError方法
asyncResult = asyncResult.whenCompleteWithContext((r, t) -> {
for (int i = filters.size() - 1; i >= 0; i--) {
Filter filter = filters.get(i);
// onResponse callback
if (filter instanceof ListenableFilter) {
Filter.Listener listener = ((ListenableFilter) filter).listener();
if (listener != null) {
if (t == null) {
listener.onResponse(r, filterInvoker, invocation);
} else {
listener.onError(t, filterInvoker, invocation);
}
}
} else {
filter.onResponse(r, filterInvoker, invocation);
}
}
});
return asyncResult;
}
}
#### 5 ConsumerContextFilter#invoke
设置上下文参数;
* 本地地址localAddress;
* 远程调用地址remoteAddress
* 远程应用名称remoteApplicationName;
* 服务参数attachments;
@Activate(group = CONSUMER, order = -10000)
public class ConsumerContextFilter extends ListenableFilter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
// 设置RpcContext参数
RpcContext.getContext()
.setInvoker(invoker)
.setInvocation(invocation)
.setLocalAddress(NetUtils.getLocalHost(), 0)
.setRemoteAddress(invoker.getUrl().getHost(), invoker.getUrl().getPort())
.setRemoteApplicationName(invoker.getUrl().getParameter(REMOTE_APPLICATION_KEY))
.setAttachment(REMOTE_APPLICATION_KEY, invoker.getUrl().getParameter(APPLICATION_KEY));
if (invocation instanceof RpcInvocation) {
((RpcInvocation) invocation).setInvoker(invoker);
}
try {
RpcContext.removeServerContext();
return invoker.invoke(invocation);
} finally {
RpcContext.removeContext();
}
}
static class ConsumerContextListener implements Listener {
@Override
public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
RpcContext.getServerContext().setAttachments(appResponse.getAttachments());
}
//....
}
}
#### 6. FutureFilter#invoke
1. 调用fireInvokeCallback判断是否有回调方法,有就触发回调方法
2. 调用下一个Invoke#invoke处理;
@Activate(group = CommonConstants.CONSUMER)
public class FutureFilter extends ListenableFilter {
@Override
public Result invoke(final Invoker<?> invoker, final Invocation invocation) throws RpcException {
fireInvokeCallback(invoker, invocation);
// need to configure if there’s return value before the invocation in order to help invoker to judge if it’s
// necessary to return future.
return invoker.invoke(invocation);
}
}
#### 7. ListenerInvokerWrapper#invoke
啥都没干,调用下一个Invoker#invoke方法;
public class ListenerInvokerWrapper implements Invoker {
private final Invoker invoker;
private final List listeners;
@Override
public Result invoke(Invocation invocation) throws RpcException {
// AsyncToSyncInvoker
return invoker.invoke(invocation);
}
}
#### 8. AsyncToSyncInvoker#invoke
public class AsyncToSyncInvoker implements Invoker {
private Invoker<T> invoker;
public AsyncToSyncInvoker(Invoker<T> invoker) {
this.invoker = invoker;
}
@Override
public Class<T> getInterface() {
return invoker.getInterface();
}
@Override
public Result invoke(Invocation invocation) throws RpcException {
// 异步转同步
Result asyncResult = invoker.invoke(invocation); // AsyncRpcResult--->CompletableFuture
try {
// 如果invocation指定是同步的,则阻塞等待结果
if (InvokeMode.SYNC == ((RpcInvocation) invocation).getInvokeMode()) {
asyncResult.get(Integer.MAX_VALUE, TimeUnit.MILLISECONDS);
}
} catch (InterruptedException e) {
//..异常处理
} catch (Throwable e) {
throw new RpcException(e.getMessage(), e);
}
return asyncResult;
}
}
#### 9. AbstractInvoker.invoke(invocation)
主要调用DubboInvoker的doInvoke方法,如果doInvoker方法出现了异常,会进行包装,包装成AsyncRpcResult
@Override
public Result invoke(Invocation inv) throws RpcException {
RpcInvocation invocation = (RpcInvocation) inv;
invocation.setInvoker(this);
invocation.setInvokeMode(RpcUtils.getInvokeMode(url, invocation));
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
try {
return doInvoke(invocation);
} catch (InvocationTargetException e) { // biz exception
Throwable te = e.getTargetException();
if (te == null) {
return AsyncRpcResult.newDefaultAsyncResult(null, e, invocation);
} else {
if (te instanceof RpcException) {
((RpcException) te).setCode(RpcException.BIZ_EXCEPTION);
}
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
{
if (te instanceof RpcException) {
((RpcException) te).setCode(RpcException.BIZ_EXCEPTION);
}
[外链图片转存中…(img-HamVm6uz-1715744524593)]
[外链图片转存中…(img-UV272s86-1715744524593)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!