-
开启feign.hystrix.enabled=true的时候, 多线程feign调用的情况下因RequestContextHolder....
2021-01-09 17:47:10<div><p>Nepxion版本: 6.5.1 Discovery Agent版本: 1.0.1 IDE: Intellj idea ...并使用javaagent进行多线程的调用,【RequestContextHolder.getRequestAttributes()】报空指针的错 报错类型: ... -
spring 多线程 或者异步 Feign 调用其他微服务 拦截时取不到request的情况
2020-08-20 19:47:28场景:在Mq的监听中,去调用其他的微服务,在对Feign进行拦截的时候报错 在链路拦截日志的RequestInterceptor中,我们可以看到通过下面方法,没有取得request的信息 RequestContextHolder.currentRequestAttributes...报错信息:
No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
场景:在Mq的监听中,去调用其他的微服务,在对Feign进行拦截的时候报错
在链路拦截日志的RequestInterceptor中,我们可以看到通过下面方法,没有取得request的信息
RequestContextHolder.currentRequestAttributes()
通过源码可以查看到是从当前ThreadLocal 中获取上下文的RequestAtrributes
当拿不到request时,创建NonWebRequestAttributes来实现RequestAttributes,然后加一个非空判断绕过强转的地方,这样就能正常的调用其他服务了
@Component public class LogFeignInterceptor implements RequestInterceptor { public LogFeignInterceptor() { } public void apply(RequestTemplate requestTemplate) { HttpServletRequest httpRequest = this.getHttpServletRequestSafely(); if (null != httpRequest && null != httpRequest.getAttribute("X-Request-No")) { requestTemplate.header("X-Request-No", new String[]{httpRequest.getAttribute("X-Request-No").toString()}); } } public HttpServletRequest getHttpServletRequestSafely() { try { RequestAttributes requestAttributesSafely = this.getRequestAttributesSafely(); return requestAttributesSafely instanceof NonWebRequestAttributes ? null : ((ServletRequestAttributes)requestAttributesSafely).getRequest(); } catch (Exception var2) { return null; } } public RequestAttributes getRequestAttributesSafely() { Object requestAttributes = null; try { requestAttributes = RequestContextHolder.currentRequestAttributes(); } catch (IllegalStateException var3) { requestAttributes = new NonWebRequestAttributes(); } return (RequestAttributes)requestAttributes; } }
-
自定义 feign 调用实现 hystrix 超时、异常熔断
2020-11-05 11:25:23FeignClient注解中配置的fallback,不需要非阻塞操作、也不需要重试,hystrix 调用feign时候做了线程池隔离处理,这样增加了项目复杂度(线程池参数配置、线程少了请求服务直接拒绝,多了线程得管理。。。) 目前...需求描述
spring cloud 项目中feign 整合 hystrix经常使用,但是最近发现hystrix功能强大,但是对我们来说有些大材小用。
首先我只需要他的一个熔断作用,就是说请求超时、异常了返回FeignClient
注解中配置的fallback
,不需要非阻塞操作、也不需要重试,hystrix 调用feign时候做了线程池隔离处理,这样增加了项目复杂度(线程池参数配置、线程少了请求服务直接拒绝,多了线程得管理。。。)
目前feign 超时之后是直接抛异常的,这样的话虽然是及时熔断了,但是正常的程序逻辑不走了配置的fallback
也没有作用,这个配置项得配合 hystrix 才行。
我需要的是这样的效果try{ feign.api(); }catch(){ return fallback(); }
但是每个feign调用都手动加上
try..catch
实在是太low了,最好能写个类似切面一样的玩意。这时候就想到了 hystrix,既然人家框架已经做了,我直接看下代码,copy不完了么
源码学习
前两天发布了一篇文章也是关于feign、hystrix 调用集成的
基于之前的分析关键代码HystrixInvocationHandler (feign.hystrix)
@Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { ............. // setterMethodMap 封装 hystrixCommand 配置信息(超时时间、是否重试.....) HystrixCommand<Object> hystrixCommand = new HystrixCommand<Object>(setterMethodMap.get(method)) { @Override protected Object run() throws Exception { .... HystrixInvocationHandler.this.dispatch.get(method).invoke(args); .... } @Override protected Object getFallback() { ......... } }; ...... return hystrixCommand.execute(); }
按照之前分析源码方式,直接看哪里被调用了就可以看到, hystrix 实际上自己封装了一个
feign.Builer
类名是feign.hystrix.HystrixFeign.Builder
用的是建造者模式,生成的类是在调用服务时用到
看到 关键的build() 方法
Feign build(final FallbackFactory<?> nullableFallbackFactory) { super.invocationHandlerFactory(new InvocationHandlerFactory() { // 重新定义一个 InvocationHandler 实现 类似 aop效果 @Override public InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch) { return new HystrixInvocationHandler(target, dispatch, setterFactory, nullableFallbackFactory); } }); super.contract(new HystrixDelegatingContract(contract)); return super.build(); }
spring 动态代理我这里不多说了,核心就是
InvocationHandler
(如果是jdk动态代理的话),那么 feign 这里也是,我们看看feign 调用声明是个接口,实际上是spring 动态代理生成了代理类,调用方法时实际调用的是java.lang.reflect.InvocationHandler#invoke
方案构想
那么我们只需要借鉴下 hystrix 的方式,自己实现一个feign.build ,将
InvocationHandler
换成自己的,
然后在我们自己的InvocationHandler
中调用feign 官方的InvocationHandler
就行,也就是feign.hystrix.HystrixInvocationHandler#invoke
这个方法中的this.dispatch.get(method).invoke(args);
这个代码方案具体代码实现
方案一
自己实现
import feign.Feign; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Component; /** * 自定义feign 构建 * @author hgf */ public class CusFeignBuilder extends Feign.Builder{ public CusFeignBuilder() { this.invocationHandlerFactory((target, dispatch) -> { Class<?> type = target.type(); FeignClient annotation = type.getAnnotation(FeignClient.class); // 构造 fallback 实例 Object fallBackObj = null; if (annotation != null && !annotation.fallback().equals(void.class)) { try { fallBackObj = annotation.fallback().newInstance(); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } } return new CusFeignInvocationHandler(target, dispatch, fallBackObj); }); } }
import feign.Feign; import feign.InvocationHandlerFactory; import feign.Target; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.openfeign.FeignClient; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import static com.eco.common.utils.Md5Util.logger; import static feign.Util.checkNotNull; /** * 自定义的feign调用 */ @Slf4j public class CusFeignInvocationHandler implements InvocationHandler { private final Target target; private final Map<Method, InvocationHandlerFactory.MethodHandler> dispatch; private final Object fallbackObj; private final Map<String, Method> fallbackMethodMap = new ConcurrentHashMap<>(); CusFeignInvocationHandler(Target target, Map<Method, InvocationHandlerFactory.MethodHandler> dispatch, Object fallbackObj) { this.target = checkNotNull(target, "target"); this.dispatch = checkNotNull(dispatch, "dispatch for %s", target); this.fallbackObj = fallbackObj; } public Object feignInvoke(Object proxy, Method method, Object[] args) throws Throwable { if ("equals".equals(method.getName())) { try { Object otherHandler = args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null; return equals(otherHandler); } catch (IllegalArgumentException e) { return false; } } else if ("hashCode".equals(method.getName())) { return hashCode(); } else if ("toString".equals(method.getName())) { return toString(); } return dispatch.get(method).invoke(args); } @Override public boolean equals(Object obj) { if (obj instanceof CusFeignInvocationHandler) { CusFeignInvocationHandler other = (CusFeignInvocationHandler) obj; return target.equals(other.target); } return false; } @Override public int hashCode() { return target.hashCode(); } @Override public String toString() { return target.toString(); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { return feignInvoke(proxy, method, args); } catch (Throwable throwable) { String configKey = Feign.configKey(target.type(), method); logger.error("{} 请求 出现异常 ==> {}", configKey, throwable.getMessage()); try { return getFallbackReturn(method, args, throwable); } catch (Throwable e) { throw throwable; } } } /** * 反射调用 {@link FeignClient#fallback()}生成失败返回值 * @param method 当前feign方法 * @param args 参数 * @param throwable 异常 */ public Object getFallbackReturn(Method method, Object[] args, Throwable throwable) throws Throwable { if (fallbackObj == null) { throw new RuntimeException("fallbackObj is null"); } String configKey = Feign.configKey(target.type(), method); Method fallbackMethod = fallbackMethodMap.get(configKey); if (fallbackMethod == null) { Class<?> declaringClass = method.getDeclaringClass(); FeignClient annotation = declaringClass.getAnnotation(FeignClient.class); if (annotation == null) { throw new RuntimeException("FeignClient annotation not found"); } // 失败返回 Class<?> fallback = annotation.fallback(); fallbackMethod = fallback.getMethod(method.getName(), method.getParameterTypes()); fallbackMethodMap.put(configKey, fallbackMethod); } if (fallbackMethod == null) { throw new RuntimeException("fallbackMethodMap not found"); } return fallbackMethod.invoke(fallbackObj, args); } }
然后在 spring 容器中注册这个bean就行
@Bean CusFeignBuilder cusFeignBuilder(){ return new CusFeignBuilder(); }
方案二
集成 sentinel ,今天写博客再回头看源码时候才发现的
加入依赖<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
配置开启
feign.sentinel.enabled=true
手动实现feign 接口,将实体类注册到 spring 中
@Component public class DeviceApiFallBack implements DeviceApi{ @Override public ServerResponse<String> login(String appId) { return ServerResponse.createByErrorMessage("请求失败"); } }
其实看代码知道原理一样,无非实现方式不一样
两个方案其实都行,方案一自己实现代码量多,方案二sentinel 官方实现,但是需要引入依赖,增加复杂度,而且 接口实现需要注册到spring 中
目前我选的还是方案一,简单
-
记一次多线程异步调取Feign接口失败问题及其解决
2019-10-21 16:16:26记一次多线程调用Feign接口失败问题及其优化 自从学会用CompletableFuture来快速构建一个异步方法,就开始到处装逼,到处优化,但是在一次线上环境中反馈短信和消息没有发出去,我赶紧排查问题,前面说下我的发短信...记一次多线程异步调取Feign接口失败问题及其解决
在一次线上环境中反馈短信和消息没有发出去,我赶紧排查问题,前面说下我的业务场景:发短信和发消息都是使用多线程异步执行,通过调取Feign来调取push服务的推送接口来进行推送,因为要快速反馈给用户消息,正好前一段时间学会用CompletableFuture,正想小试牛刀的我,依然决然采用之来实现异步推送,本来用起来还蛮好的,简单易懂方便,而且支持线程窃取等一系列功能,简直是如获至宝,但是今天线上突然出现了以下错误,泼了我一脸冷水:
Task java.util.concurrent.FutureTask@68bb4099 rejected from java.util.concurrent.ThreadPoolExecutor@f8b8538[Running, pool size = 10, active threads = 10, queued tasks = 20, completed tasks = 693]
开始一度以为是CompletableFuture的锅,但是经过我百度了会,发现其实我错怪了CompleteFuture了,一开始还去看CompleteFuture的源码,了解到CompletableFuture用的是ForkJoinPool的线程池,默认线程数是系统机的cpu核心数,但这个错误为啥报的是active threads=10,这个我就郁闷了,而且CompletableFuture默认会给每个工作线程分配独立的队列,应该不会出现并发调直接拒绝我的任务的问题啊!思前想后我还是想不通,后来索性把堆栈打出来了,我这才知道是Hystrix的问题:
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@6900a95d rejected from java.util.concurrent.ThreadPoolExecutor@5d2de59a[Running, pool size = 10, active threads = 10, queued tasks = 20, completed tasks = 54] at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063) at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112) at com.netflix.hystrix.strategy.concurrency.HystrixContextScheduler$ThreadPoolWorker.schedule(HystrixContextScheduler.java:172) at com.netflix.hystrix.strategy.concurrency.HystrixContextScheduler$HystrixContextSchedulerWorker.schedule(HystrixContextScheduler.java:106) at rx.internal.operators.OperatorSubscribeOn.call(OperatorSubscribeOn.java:50) at rx.internal.operators.OperatorSubscribeOn.call(OperatorSubscribeOn.java:30) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) at rx.Observable.unsafeSubscribe(Observable.java:10327) ....
原来是com.netflix.hystrix下面爆出来的错,o(╥﹏╥)o,找了好久,终于找到了,好了,知道了问题所在,我们开始分析为啥会报这错。之后发现一旦并发量大的时候,就会报,我一想这不就是hystrix熔断机制吗?自己然后查了下资料,发现hystrix调用其他服务的时候核心最大Threadsize=10,如果核心线程达到最大线程则直接拒绝,而且默认没有队列,可能hystrix是为了快速调用才这么设计,但根据我的业务此涉及不太靠谱,所以我就想着直接扩大线程数,但是最大线程数也不能乱调,大了会增加线程上下文切换,小了效率又不高,导致又会拒绝我的任务执行,后来查了下官网,有了如下解决方法,不多说直接贴出一下配置:
hystrix: threadpool: default: coreSize: 16//并发执行的最大线程数,默认10,我这里用cpu核心数 maxQueueSize: 1000//BlockingQueue的最大队列数,默认值-1 queueSizeRejectionThreshold: 800 //即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝,默认值5
配置直接放在application.yml中,这样遇到某些场景远程调用并发多的时候可以采用以上配置,但这个配置也不能乱用,因为加了队列,这就意味着你的熔断门槛就比较高了,所以各位同学一定要根据自己的业务场景来设置。
-
解决Spring cloud项目中多线程中使用feign访问其他服务失败问题
2020-04-17 10:00:47微服务中尝试使用多线程访问其他服务,通过服务接口调用失败, 通过Debug模式,跟随子线程调用链,发现处理服务发送时的请求头设置中, ServletRequestAttributes attributes = (ServletRequestAttributes) ...微服务中尝试使用多线程访问其他服务,通过服务接口调用失败,
通过Debug模式,跟随子线程调用链,发现处理服务发送时的请求头设置中,
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder .getRequestAttributes(); HttpServletRequest request = attributes.getRequest();
获取的request为null,
通过度娘几番查找,找到一篇文章解决request为null的问题,
https://blog.csdn.net/schcilin/article/details/92403362
通过文章发现,在Spring cloud微服务中,feign开启了熔断器(hystrix):feign.hystrix.enabled=ture,并且使用默认的信号隔离级别,、HttpServletRequest对象在父线程与子线程是相互独立的,不共享的。所以子线程中使用父线程的HttpServletRequest数据为null。
在我的测试代码中使用feign API接口前调用
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
来设置将父线程的HttpServletRequest对象设置共享,
-
【小笔记】SpringCloud Feign子线程调用丢失Request问题
2020-06-23 00:35:05该逻辑中涉及多个子系统之间的调用,原本的调用方式为使用RestTemplate,走服务名调用,并没有问题。后来接口改造为了调用方便,引入feign,于是导致获取不到irequest上下文及无法传递header及cookie等问题。 问题... -
微服务之间共享threadlocal_多线程调用如何传递请求上下文?简述ThreadLocal和TaskDecorator...
2020-12-22 14:49:27背景微服务应用大多对外提供RESTful API,需要有相应的token才能访问,我们在聚合服务中使用Feign Client调用这些API,顺序执行往往会浪费大量的IO等待时间,为了提高查询速度,我们会使用异步调用,Java 8引入了... -
Spring Cloud Feign 记录单个服务耗时并解决 Hystrix 线程隔离模式
2020-12-04 21:02:54随着公司业务的增长,系统的调用量也越来越多。对于第三方公司的我们,如何提高系统的稳定性是摆在我们面前的一个问题。为了解决系统稳定性问题,决定把整个服务的日志通过日志跟踪号(traceNo) 以及一次调用链中每一... -
Hystrix熔断器、Feign客户端
2020-12-03 22:04:55微服务中,服务间调用关系错综复杂,一个服务的业务,有可能需要调用多个其它微服务,才能完成。 如图,如果说,我们需要访问的某个服务,Dependency-I发生了故障,此时,我们应用中,调用Dependency-I的服务,也会... -
【Spring Cloud】【Hystrix】Feign下Hystrix的简单熔断测试
2020-12-05 18:34:10如下图,对于同步调用,当库存服务不可用时,商品服务请求线程被阻塞,当有大批量请求调用库存服务时,最终可能导致整个商品服务资源耗尽,无法继续对外提供服务。并且这种不可用可能沿请求调用链向上传递,这种现象... -
SpringCloud中Service类注入同服务下(@Feign)api接口不走http的解决方案
2018-04-22 00:41:24在我们使用@Feign的时候,其实是用本质上采用的是http调用摸个服务下的其接口实现,那么http调用的话,就会多产生一个线程,如图测试, 2018-04-22 00:37:26.517 INFO 24548 --- [nio-9999-exec-4] c.d.c.eureka.... -
Springboot异步方法,线程上下文传递丢失问题
2020-07-23 17:25:21在异步方法中,需要用feign调用B服务获取相关数据,因为有鉴权的存在,所以异步方法调用B服务接口的时候也要携带token 那么就涉及到线程上下文的问题,配置了线程池,然后设置了线程上下文的数据切换(见下图) !... -
【SpringCloud】负载均衡Rebbon 熔断Hystrix(防止雪崩问题) Feign(根据参数拼接http请求) Gateway(拦截器/...
2020-11-27 09:43:06线程隔离 1.负载均衡 1.介绍 负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行 本质:负载均衡是一个算法,可以通过该算法实现从地址列表中获取一个地址进行服务调用。 Ribbon提供了**轮询、随机两... -
Hystrix的资源隔离
2021-02-27 15:27:52feign调用过程中,若开启了Hystrix熔断,则feign调用接口将是经过代理的Hystrix类。 对于每个feign client都会在服务启动时,创建名称为该应用名的线程池,默认10个核心线程数。 2、信号量 信号量这个并不是... -
Java多用户商城系统B2B2C源码 -JAVA B2B2C 多用户商城 (四)断路器(Hystrix)
2019-03-18 08:31:39在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的... -
Java springboot B2B2C o2o多用户商城 springcloud架构(四)断路器(Hystrix)
2019-04-03 09:29:52在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的... -
java B2B2C springmvc mybatis多租户电子商城系统-(四)断路器(Hystrix)
2019-01-22 02:14:10在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的... -
fat:基于springboot,zookeeper,redis分布式事务强一致性方案-源码
2021-02-06 10:39:54基于注解使用,对业务代码可以说是零入侵,目前内置适配spring-cloud(Feign调用),dubbo。同时具有一定的扩展性与兼容性,因为存在自定义的服务框架,或者以后会涌现出更多的流行分布式服务框架,所以会提供一些... -
Spring Cloud | 第四篇:断路器(Hystrix)
2018-06-23 14:31:40一、Hystrix简介Hystrix是Netflix开源的一款容错框架,包含常用的容错方法:线程隔离、信号量隔离、降级策略、熔断技术。在高并发访问下,系统所依赖...本篇文章基于前一篇文章的工程二:使用Feign调用服务中使用Hy... -
SpringCloud项目中用jmeter测试 测试效率比单体服务器负载的效率还差?
2019-05-11 02:21:55结果很是奇怪 利用feign负载均衡算法之后请求错误率竟然比直接访问clientA的错误率还高 按理来说已经是两台服务器的client负载均衡 就算异常率减少的不多 也不应该比原来更高啊 希望有个大佬帮我分析一下原因 ... -
Spring Cloud中如何优雅的使用Feign调用接口:http://cxytiandi.com/blog/detail/12189 Spring Cloud Feign fallback错误解决:http://cxytiandi.com/blog/detail/12368 Spring Cloud Feign 启动Unsatisfied...
-
Hystrix的简单应用(五)
2020-02-17 14:46:58在微服务架构中,根据业务来拆分成一个个的服务,而服务与服务之间存在着依赖关系,在SpringCloud中多个微服务之间可以用RestTemplate + Ribbon 和Feign来调用。在服务之间调用的链路上由于网络原因,资源繁忙或者... -
Sleuth
2019-02-02 17:27:17文章目录原理介绍Brave和Zipkin使用依赖Sleuth对feign的支持Sleuth对RestTemplate的支持Sleuth对多线程的支持 原理介绍 Sleuth通过Trace定义一次业务调用链,根据它的信息,我们就知道多少个系统参与了该业务处理。 ... -
【SpringCloud】12 Hystrix 熔断器
2020-06-12 09:27:34商品调库存,库存调订单等等),在Spring Cloud中多个微服务之间可以用 RestTemplate+Ribbon 和 Feign 来调用。 2、分布式微服务架构面临的问题 a:在服务之间调用的链路上由于网络原因、资源繁忙或者自身的原因,... -
hystrix的服务降级
2020-08-24 23:20:21而线程/进程对应着系统资源,如果得不到释放的线程/进程就会越积越多,资源就会被耗尽,最终导致服务不可用!hystrix就是解决这类问题的工具类库。 服务降级 用自己的话来说,就是当某个服务不可用的时候,有一个... -
SpringBoot2 整合 SpringCloud 的 Hystrix断路器 实例
2019-10-17 19:32:37微服务架构中服务之间互相调用,单个服务通常会集群部署,由于网络等原因,服务不能保证 100% 可用,如果单个服务出现问题会出现请求的堆积,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。 2. 短路器 一个请求... -
SpringCloud (八) Hystrix 请求缓存的使用
2018-05-21 10:17:00脱更了半个月多,今天项目的初版已经完成,所以打算继续我们的微服务学习,由于Hystrix这一块东西好多,只好多拆分几篇文章写,对于一般对性能要求不是很高的项目中,可以使用其基础上开发的Feign进行容错保护。... -
springCloud
2018-08-09 16:54:33这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。 断路器示意图 SpringCloud Netflix实现了断路器库的名字叫Hystrix. 在微服务架构下,通常会有多个层次的服务调用. 下面是... -
大型互联网级企业架构师视频教程 JAVA高级架构师必备课程 82G超强的JAVA架构师课程
2019-11-08 21:55:47大型互联网级企业架构师视频教程 JAVA高级架构师必备课程 82G超强的JAVA架构师课程 ===============课程目录=============== ...├─(170) 调用链系统服务端实现 2018-06-26 20-09-48-357-.mp4 (32)\\07.解决方案专题...
-
libFuzzer视频教程
-
app软件测试全栈系列精品课程
-
uci1960c_a0.1.pdf
-
项目管理工具与方法
-
在 Linux 上构建企业级 DNS 域名解析服务
-
node基础
-
精通编译Makefile,Nina, 从底层uboot到Android
-
基于Qt的LibVLC开发教程
-
Mysql根据身份证修改年龄
-
TL1788_V0.8_20060401.pdf
-
5692. 车队 II
-
理财学习02-基金误区
-
【布道者】Linux极速入门
-
自定义拍照、录制视频工具类.zip
-
TL1765_V0.0_20070719.pdf
-
TL1769_Initial Sequence_20050812.pdf
-
MySQL 高可用(DRBD + heartbeat)
-
PDF转PPT工具.rar
-
EMVCo 4.3 英文版本
-
OTM1285A_DATA SHEET_V0.2_TIANMA.pdf