private void copyThreadLocalToMetadata(Metadata headers) { Map<String, String> attachments = RpcContext.getContext().getAttachments(); Map<String, Object> values = RpcContext.getContext().get(); try { if (!attachments.isEmpty()) { headers.put(GrpcUtil.GRPC_CONTEXT_ATTACHMENTS, SerializerUtil.toJson(attachments)); } if (!values.isEmpty()) { headers.put(GrpcUtil.GRPC_CONTEXT_VALUES, SerializerUtil.toJson(values)); } } catch (Throwable e) { log.error(e.getMessage(), e); } finally { RpcContext.removeContext(); } } }
public GrpcRouter getGrpcRouter(String serivceKey) { String currentRouterRule = null; // 从线程上下文取路由规则 if (RpcContext.getContext().containAttachment("routerRule")) { currentRouterRule = RpcContext.getContext().getAttachment("routerRule"); } // 从配置中心获取路由规则并覆盖线程上下文的路由规则 String configRouterRule = ROUTE_CACHE.getIfPresent(serivceKey); if (configRouterRule != null) { currentRouterRule = configRouterRule; } if (currentRouterRule != null) { try { return this.createRouter(currentRouterRule); } finally { RpcContext.getContext().removeAttachment("routerRule"); } } else { return null; } }
protected void cacheCurrentServer() { Object obj = GrpcCallOptions.getAffinity(this.request.getRefUrl()) .get(GrpcCallOptions.GRPC_CURRENT_ADDR_KEY); if (obj != null) { InetSocketAddress currentServer = (InetSocketAddress) obj; RpcContext.getContext().setAttachment(Constants.REMOTE_ADDRESS, currentServer.getHostName()); } } }
@Override protected Object run() throws Exception { try { RpcContext.getContext().setAttachments(rpcContext.getLeft()); RpcContext.getContext().set(rpcContext.getMiddle()); RpcContext.getContext().setHoldenGroups(rpcContext.getRight()); MethodDescriptor<Message, Message> methodDesc = this.request.getMethodDescriptor(); Integer timeOut = this.request.getCallTimeout(); Message request = getRequestMessage(); Message response = this.run0(request, methodDesc, timeOut, clientCall); Object obj = this.transformMessage(response); collectLogExecutor.execute(new Runnable() { @Override public void run() { collect(serviceName, methodName, request, response, false); } }); return obj; } finally { RpcContext.removeContext(); } }
@RequestMapping(value = "testLocal", method = RequestMethod.POST) public Object testLocalService( @RequestParam(value = "routerRule", required = true) String routerRule, @RequestBody GrpcServiceTestModel model) throws ClassNotFoundException { try { Class<?> requestClass = ReflectUtils.name2class(model.getParameterType()); Object request = gson.fromJson(model.getParameter(), requestClass); Object[] args = new Object[] {request}; if (StringUtils.isNotBlank(routerRule)) { RpcContext.getContext().setAttachment("routerRule", routerRule); } else { RpcContext.getContext().removeAttachment("routerRule"); } Object reply = genricService.$invoke(model.getService(), getAnnotation(model.getService()).getLeft(), getAnnotation(model.getService()).getRight(), model.getMethod(), args); return reply; } catch (ClassNotFoundException e) { throw e; } }
private void copyMetadataToThreadLocal(Metadata headers) { String attachments = headers.get(GrpcUtil.GRPC_CONTEXT_ATTACHMENTS); String values = headers.get(GrpcUtil.GRPC_CONTEXT_VALUES); try { if (attachments != null) { Map<String, String> attachmentsMap = SerializerUtil.fromJson(attachments, new TypeToken<Map<String, String>>() {}.getType()); RpcContext.getContext().setAttachments(attachmentsMap); } if (values != null) { Map<String, Object> valuesMap = SerializerUtil.fromJson(values, new TypeToken<Map<String, Object>>() {}.getType()); for (Map.Entry<String, Object> entry : valuesMap.entrySet()) { RpcContext.getContext().set(entry.getKey(), entry.getValue()); } } } catch (Throwable e) { log.error(e.getMessage(), e); } } }
@Override public void invoke(Message request, StreamObserver<Message> responseObserver) { this.remote = RpcContext.getContext().getAttachment(Constants.REMOTE_ADDRESS); switch (grpcMethodType.methodType()) { case UNARY: unaryCall(request, responseObserver); break; case SERVER_STREAMING: streamCall(request, responseObserver); break; default: break; } }
@Override protected RpcContext initialValue() { return new RpcContext(); } };
@Override public StreamObserver<Message> invoke(StreamObserver<Message> responseObserver) { try { this.remote = RpcContext.getContext().getAttachment(Constants.REMOTE_ADDRESS); Class<?> requestType = grpcMethodType.requestType(); PoJo2ProtoStreamObserver servserResponseObserver = PoJo2ProtoStreamObserver.newObserverWrap(responseObserver); Object result = method.invoke(serviceToInvoke, servserResponseObserver); return Proto2PoJoStreamObserver.newObserverWrap((StreamObserver<Object>) result, requestType); } catch (Throwable e) { String stackTrace = ThrowableUtil.stackTraceToString(e); log.error(e.getMessage(), e); StatusRuntimeException statusException = Status.UNAVAILABLE.withDescription(stackTrace).asRuntimeException(); responseObserver.onError(statusException); } finally { log.debug(String.format("Service: %s Method: %s RemoteAddress: %s", providerUrl.getServiceInterface(), method.getName(), this.remote)); } return null; }
public GrpcHystrixCommand(String serviceName, String methodName, Boolean isEnabledFallBack) { super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(serviceName))// .andCommandKey(HystrixCommandKey.Factory.asKey(serviceName + ":" + methodName))// .andCommandPropertiesDefaults( HystrixCommandProperties.Setter().withCircuitBreakerRequestVolumeThreshold(20)// 10秒钟内至少19此请求失败,熔断器才发挥起作用 .withCircuitBreakerSleepWindowInMilliseconds(30000)// 熔断器中断请求30秒后会进入半打开状态,放部分流量过去重试 .withCircuitBreakerErrorThresholdPercentage(50)// 错误率达到50开启熔断保护 .withExecutionTimeoutEnabled(false)// 禁用这里的超时 .withFallbackEnabled(isEnabledFallBack))// .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(100) .withAllowMaximumSizeToDivergeFromCoreSize(true).withMaximumSize(Integer.MAX_VALUE))); this.serviceName = serviceName; this.methodName = methodName; this.start = System.currentTimeMillis(); this.rpcContext = new ImmutableTriple<Map<String, String>, Map<String, Object>, Set<Class>>( RpcContext.getContext().getAttachments(), RpcContext.getContext().get(), RpcContext.getContext().getHoldenGroups()); RpcContext.removeContext(); }
private void contextCopy(ServerCall<?, ?> call, final Metadata headers) { copyMetadataToThreadLocal(headers); InetSocketAddress remoteAddress = (InetSocketAddress) call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR); RpcContext.getContext().setAttachment(Constants.REMOTE_ADDRESS, remoteAddress.getHostString()); }