SpringCloud之RPC适配实践

导言

SpringCloud大家初次使用的时候,都有一个疑惑,官网推崇的是restful,但RPC该如何支持?本文旨在为大家提供一个思路,至于如何集成到大家自己的框架中还需要各自针对自己的情况好好思考。

思路

我们拿基于spring包装的hessian框架举例。构造HessianProxyFactoryBean对象时,原生是需要传入url,这里我们改成传入调用的服务名称和服务暴露的路径。扩展HessianClientInterceptor的invoke代码,原先获取hessianProxy的代码改为根据ribbon拿到的url缓存的hessianProxy,如果不存在则创建并加入缓存中。其他功能不变,即可实现hessian对eureka的支持。

关键代码

  • 继承HessianClientInterceptor,覆盖invoke方法
HessianClientInterceptor中invoke的代码为:

@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
		if (this.hessianProxy == null) {
			throw new IllegalStateException("HessianClientInterceptor is not properly initialized - " +
					"invoke 'prepare' before attempting any operations");
		}

		ClassLoader originalClassLoader = overrideThreadContextClassLoader();
		try {
			return invocation.getMethod().invoke(this.hessianProxy, invocation.getArguments());
		}
		catch (InvocationTargetException ex) {

    ...
}

扩展代码为:

@Override
public Object invoke(MethodInvocation invocation) throws Throwable {

        Object hessianProxy = null;

        String url = null;

        try {
            url = this.getServiceUrl();
            hessianProxy = hessianProxyMap.get(url);
            if (hessianProxy == null) {
                hessianProxy = proxyFactory.create(getServiceInterface(), url, getBeanClassLoader());
                hessianProxyMap.put(url, hessianProxy);
            }
        } catch (MalformedURLException ex) {
            throw new RemoteLookupFailureException("Service URL [" + url + "] is invalid", ex);
        }

  if (hessianProxy == null) {
            throw new IllegalStateException("HessianProxy init fail, service url : " + url);
        }

        ClassLoader originalClassLoader = overrideThreadContextClassLoader();
        try {
            return invocation.getMethod().invoke(hessianProxy, invocation.getArguments());
        } catch (InvocationTargetException ex) {
  ...
}

  • 调用Ribbon API获取服务url, 注意如果应用有contextpath,可以利用eureka的metaData进行保存,即app配置euraka的配置中增加metadata的配置。
@Autowired
private LoadBalancerClient  loadBalancer;

@Override
public String selectUrl(String serviceName) throws NoServiceUrlFoundException {

  ServiceInstance serviceInstance = loadBalancer.choose(serviceName);
  if (serviceInstance == null) {
      throw new NoServiceUrlFoundException("No valid serviceUrl find from RegServer by serviceName: " + serviceName);
  }

  StringBuffer sb = new StringBuffer(serviceInstance.getUri().toString());
  if (serviceInstance.getMetadata() != null && serviceInstance.getMetadata().containsKey(KEY_CONTEXT_PATH) &&
              StringUtils.isNotEmpty(serviceInstance.getMetadata().get(KEY_CONTEXT_PATH)))  {
      String contextPath = serviceInstance.getMetadata().get(KEY_CONTEXT_PATH);
      if (!contextPath.startsWith("/")) {
          sb.append("/");
      }
      sb.append(contextPath);
 }
  return sb.toString();
}

转载于:https://my.oschina.net/u/2408085/blog/714020

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值