日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Spring Cloud Feign內(nèi)部實(shí)現(xiàn)代碼細(xì)節(jié)

瀏覽:64日期:2023-07-14 14:57:44
1. 概述

Feign用于服務(wù)間調(diào)用,它的內(nèi)部實(shí)現(xiàn)是一個(gè)包含Ribbon(負(fù)載均衡)的**JDK-HttpURLConnection(Http)**調(diào)用。雖然調(diào)用形式是類似于RPC,但是實(shí)際調(diào)用是Http,這也是為什么Feign被稱為偽RPC調(diào)用的原因。內(nèi)部調(diào)用過程如下:

Spring Cloud Feign內(nèi)部實(shí)現(xiàn)代碼細(xì)節(jié)

2. 代碼細(xì)節(jié)

1) BaseLoadBalancer.java配置初始化

重點(diǎn)功能: 1. 初始化負(fù)載均衡策略 2. 初始化取服務(wù)注冊(cè)列表調(diào)度策略

void initWithConfig(IClientConfig clientConfig, IRule rule, IPing ping, LoadBalancerStats stats) { ... // 每隔30s Ping一次 int pingIntervalTime = Integer.parseInt('' + clientConfig.getProperty( CommonClientConfigKey.NFLoadBalancerPingInterval, Integer.parseInt('30'))); // 每次最多Ping 2s int maxTotalPingTime = Integer.parseInt('' + clientConfig.getProperty( CommonClientConfigKey.NFLoadBalancerMaxTotalPingTime, Integer.parseInt('2'))); setPingInterval(pingIntervalTime); setMaxTotalPingTime(maxTotalPingTime); // cross associate with each other // i.e. Rule,Ping meet your container LB // LB, these are your Ping and Rule guys ... // 設(shè)置負(fù)載均衡規(guī)則 setRule(rule); // 初始化取服務(wù)注冊(cè)列表調(diào)度策略 setPing(ping); setLoadBalancerStats(stats); rule.setLoadBalancer(this); ...}

2) 負(fù)載均衡策略初始化

重點(diǎn)功能: 1. 默認(rèn)使用輪詢策略

BaseLoadBalancer.java

public void setRule(IRule rule) { if (rule != null) {this.rule = rule; } else {/* default rule */// 默認(rèn)使用輪詢策略this.rule = new RoundRobinRule(); } if (this.rule.getLoadBalancer() != this) {this.rule.setLoadBalancer(this); }}

RoundRobinRule.java

private AtomicInteger nextServerCyclicCounter;public Server choose(ILoadBalancer lb, Object key) { if (lb == null) {log.warn('no load balancer');return null; } Server server = null; int count = 0; while (server == null && count++ < 10) {List<Server> reachableServers = lb.getReachableServers();List<Server> allServers = lb.getAllServers();int upCount = reachableServers.size();int serverCount = allServers.size();if ((upCount == 0) || (serverCount == 0)) { log.warn('No up servers available from load balancer: ' + lb); return null;}// 輪詢重點(diǎn)算法int nextServerIndex = incrementAndGetModulo(serverCount);server = allServers.get(nextServerIndex);if (server == null) { /* Transient. */ Thread.yield(); continue;}if (server.isAlive() && (server.isReadyToServe())) { return (server);}// Next.server = null; } if (count >= 10) {log.warn('No available alive servers after 10 tries from load balancer: '+ lb); } return server;}private int incrementAndGetModulo(int modulo) { for (;;) {int current = nextServerCyclicCounter.get();int next = (current + 1) % modulo;if (nextServerCyclicCounter.compareAndSet(current, next)) return next; }}

3) 初始化取服務(wù)注冊(cè)列表調(diào)度策略

重點(diǎn)功能: 1. 設(shè)置輪詢間隔為30s 一次

注意: 這里沒有做實(shí)際的Ping,只是獲取緩存的注冊(cè)列表的alive服務(wù),原因是為了提高性能

BaseLoadBalancer.java

public void setPing(IPing ping) { if (ping != null) {if (!ping.equals(this.ping)) { this.ping = ping; setupPingTask(); // since ping data changed} } else {this.ping = null;// cancel the timer tasklbTimer.cancel(); }}void setupPingTask() { if (canSkipPing()) {return; } if (lbTimer != null) {lbTimer.cancel(); } lbTimer = new ShutdownEnabledTimer('NFLoadBalancer-PingTimer-' + name, true); // 這里雖然默認(rèn)設(shè)置是10s一次,但是在初始化的時(shí)候,設(shè)置了30s一次 lbTimer.schedule(new PingTask(), 0, pingIntervalSeconds * 1000); forceQuickPing();}class Pinger { private final IPingStrategy pingerStrategy; public Pinger(IPingStrategy pingerStrategy) {this.pingerStrategy = pingerStrategy; } public void runPinger() throws Exception {if (!pingInProgress.compareAndSet(false, true)) { return; // Ping in progress - nothing to do}// we are 'in' - we get to PingServer[] allServers = null;boolean[] results = null;Lock allLock = null;Lock upLock = null;try { /* * The readLock should be free unless an addServer operation is * going on... */ allLock = allServerLock.readLock(); allLock.lock(); allServers = allServerList.toArray(new Server[allServerList.size()]); allLock.unlock(); int numCandidates = allServers.length; results = pingerStrategy.pingServers(ping, allServers); final List<Server> newUpList = new ArrayList<Server>(); final List<Server> changedServers = new ArrayList<Server>(); for (int i = 0; i < numCandidates; i++) {boolean isAlive = results[i];Server svr = allServers[i];boolean oldIsAlive = svr.isAlive();svr.setAlive(isAlive);if (oldIsAlive != isAlive) { changedServers.add(svr); logger.debug('LoadBalancer [{}]: Server [{}] status changed to {}', name, svr.getId(), (isAlive ? 'ALIVE' : 'DEAD'));}if (isAlive) { newUpList.add(svr);} } upLock = upServerLock.writeLock(); upLock.lock(); upServerList = newUpList; upLock.unlock(); notifyServerStatusChangeListener(changedServers);} finally { pingInProgress.set(false);} }}private static class SerialPingStrategy implements IPingStrategy { @Override public boolean[] pingServers(IPing ping, Server[] servers) {int numCandidates = servers.length;boolean[] results = new boolean[numCandidates];logger.debug('LoadBalancer: PingTask executing [{}] servers configured', numCandidates);for (int i = 0; i < numCandidates; i++) { results[i] = false; /* Default answer is DEAD. */ try {// NOTE: IFF we were doing a real ping// assuming we had a large set of servers (say 15)// the logic below will run them serially// hence taking 15 times the amount of time it takes// to ping each server// A better method would be to put this in an executor// pool// But, at the time of this writing, we dont REALLY// use a Real Ping (its mostly in memory eureka call)// hence we can afford to simplify this design and run// this// seriallyif (ping != null) { results[i] = ping.isAlive(servers[i]);} } catch (Exception e) {logger.error('Exception while pinging Server: ’{}’', servers[i], e); }}return results; }}

4) 最后拼接完整URL使用JDK-HttpURLConnection進(jìn)行調(diào)用

SynchronousMethodHandler.java(io.github.openfeign:feign-core:10.10.1/feign.SynchronousMethodHandler.java)

Object executeAndDecode(RequestTemplate template, Options options) throws Throwable { Request request = this.targetRequest(template); if (this.logLevel != Level.NONE) {this.logger.logRequest(this.metadata.configKey(), this.logLevel, request); } long start = System.nanoTime(); Response response; try {response = this.client.execute(request, options);response = response.toBuilder().request(request).requestTemplate(template).build(); } catch (IOException var13) {if (this.logLevel != Level.NONE) { this.logger.logIOException(this.metadata.configKey(), this.logLevel, var13, this.elapsedTime(start));}throw FeignException.errorExecuting(request, var13); } ...}

LoadBalancerFeignClient.java

@Overridepublic Response execute(Request request, Request.Options options) throws IOException { try {URI asUri = URI.create(request.url());String clientName = asUri.getHost();URI uriWithoutHost = cleanUrl(request.url(), clientName);FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(this.delegate, request, uriWithoutHost);IClientConfig requestConfig = getClientConfig(options, clientName);return lbClient(clientName).executeWithLoadBalancer(ribbonRequest, requestConfig).toResponse(); } catch (ClientException e) {IOException io = findIOException(e);if (io != null) { throw io;}throw new RuntimeException(e); }}

AbstractLoadBalancerAwareClient.java

public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException { LoadBalancerCommand<T> command = buildLoadBalancerCommand(request, requestConfig); try {return command.submit( new ServerOperation<T>() {@Overridepublic Observable<T> call(Server server) { // 獲取真實(shí)訪問URL URI finalUri = reconstructURIWithServer(server, request.getUri()); S requestForServer = (S) request.replaceUri(finalUri); try {return Observable.just(AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig)); } catch (Exception e) {return Observable.error(e); }} }) .toBlocking() .single(); } catch (Exception e) {Throwable t = e.getCause();if (t instanceof ClientException) { throw (ClientException) t;} else { throw new ClientException(e);} } }

FeignLoadBalancer.java

@Overridepublic RibbonResponse execute(RibbonRequest request, IClientConfig configOverride)throws IOException { Request.Options options; if (configOverride != null) {RibbonProperties override = RibbonProperties.from(configOverride);options = new Request.Options(override.connectTimeout(this.connectTimeout),override.readTimeout(this.readTimeout)); } else {options = new Request.Options(this.connectTimeout, this.readTimeout); } Response response = request.client().execute(request.toRequest(), options); return new RibbonResponse(request.getUri(), response);}

feign.Client.java

@Overridepublic Response execute(Request request, Options options) throws IOException { HttpURLConnection connection = convertAndSend(request, options); return convertResponse(connection, request);}Response convertResponse(HttpURLConnection connection, Request request) throws IOException { // 使用HttpURLConnection 真實(shí)進(jìn)行Http調(diào)用 int status = connection.getResponseCode(); String reason = connection.getResponseMessage(); if (status < 0) { throw new IOException(format('Invalid status(%s) executing %s %s', status,connection.getRequestMethod(), connection.getURL())); } Map<String, Collection<String>> headers = new LinkedHashMap<>(); for (Map.Entry<String, List<String>> field : connection.getHeaderFields().entrySet()) { // response message if (field.getKey() != null) { headers.put(field.getKey(), field.getValue()); } } Integer length = connection.getContentLength(); if (length == -1) { length = null; } InputStream stream; if (status >= 400) { stream = connection.getErrorStream(); } else { stream = connection.getInputStream(); } return Response.builder() .status(status) .reason(reason) .headers(headers) .request(request) .body(stream, length) .build();}

拓展干貨閱讀:一線大廠面試題、高并發(fā)等主流技術(shù)資料

以上就是Spring Cloud Feign內(nèi)部實(shí)現(xiàn)代碼細(xì)節(jié)的詳細(xì)內(nèi)容,更多關(guān)于Spring Cloud Feign的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
欧美综合精品| 亚洲综合五月| 黄页网站一区| 日韩三区四区| 欧美在线首页| 日韩在线精品| 老司机精品久久| 另类中文字幕国产精品| 97久久超碰| 日韩午夜在线| 国产精品综合色区在线观看| 欧美片第1页综合| 欧美日韩少妇| 日韩二区三区四区| 亚洲高清成人| 久久三级毛片| 老牛影视一区二区三区| 日产午夜精品一线二线三线| 欧美国产中文高清| 亚洲精品系列| 日韩精品中文字幕第1页| av免费不卡国产观看| 正在播放日韩精品| 免费日韩一区二区三区| av成人国产| 亚洲精品91| 久久精品天堂| 国产视频一区三区| 国产精品免费不| 精品国产精品国产偷麻豆| 日韩欧美激情| 久久精品 人人爱| 久久精品理论片| 久久精品亚洲人成影院| 999国产精品视频| 亚洲精品伊人| 中文字幕在线官网| 日韩av一区二| 蘑菇福利视频一区播放| 日韩精品免费观看视频| 婷婷精品在线| 婷婷亚洲综合| 午夜欧美精品| 夜鲁夜鲁夜鲁视频在线播放| 精品国产美女a久久9999| 久久精品xxxxx| 国产日韩欧美高清免费| 老司机精品视频网| 美女黄网久久| 久久精品国内一区二区三区| 综合亚洲自拍| av高清一区| 亚洲欧美伊人| 日韩高清二区| 亚洲精品在线国产| 亚洲欧美日韩国产一区二区| 日本成人中文字幕在线视频| 91精品国产自产在线丝袜啪| 日韩精品电影一区亚洲| 国产精品第十页| 91中文字幕精品永久在线| 午夜电影亚洲| 欧美日韩夜夜| 欧美久久天堂| 日韩精品免费视频一区二区三区| 电影亚洲精品噜噜在线观看 | 国产精品nxnn| 亚洲国产一区二区在线观看| 国产探花在线精品一区二区| 亚洲二区在线| 久久中文欧美| 亚洲精品伊人| 99久久精品国产亚洲精品| 日韩av资源网| 一级欧洲+日本+国产| 精品一区二区三区四区五区| 国产免费成人| 日韩一区二区三区免费| 国产精品xxx在线观看| 99成人在线| 91中文字幕精品永久在线| **爰片久久毛片| 在线亚洲免费| 88xx成人免费观看视频库| 国产精品白丝久久av网站| 综合欧美亚洲| 夜夜精品视频| 视频小说一区二区| 老司机免费视频一区二区| 日韩精品一区二区三区中文| 一区视频在线| 亚洲精品永久免费视频| 国产欧美久久一区二区三区| 最新亚洲国产| 美女久久一区| 国精品一区二区| 欧美日韩尤物久久| 国产精品久久久久久久久妇女| 欧美亚洲三区| 天堂va欧美ⅴa亚洲va一国产| 黄色精品网站| 99精品视频精品精品视频| 国产第一亚洲| 欧美精品99| 国产精品一区二区三区www| 日本亚洲最大的色成网站www | 中文字幕免费精品| 影音先锋久久| 婷婷激情综合| 亚洲福利精品| 黑丝一区二区三区| 好吊视频一区二区三区四区| 久久亚洲成人| 国产在线|日韩| 成人亚洲欧美| 成人在线黄色| 精品国产乱码久久久久久1区2匹| 国产美女久久| 亚洲精品伦理| 日本欧洲一区二区| 免费高清在线一区| 热久久久久久久| 日韩一区精品字幕| 亚洲麻豆一区| 日韩精选在线| 青青青国产精品| 国产欧美日韩视频在线 | 久久久国产亚洲精品| 日本免费一区二区视频| 欧美三区四区| jizzjizz中国精品麻豆| 欧美综合社区国产| 尹人成人综合网| 成人久久久久| 综合亚洲视频| 午夜国产欧美理论在线播放| 久久精品中文| 午夜精品亚洲| 丝袜美腿亚洲色图| 亚洲人成网站在线在线观看| 四虎在线精品| 国产午夜精品一区在线观看| 国产亚洲久久| 国产成人77亚洲精品www| 中文字幕一区久| 免费成人网www| 国产综合婷婷| 久久亚洲一区| 日韩毛片网站| 国产精久久久| 蜜臀久久精品| 亚洲中字黄色| 日韩1区2区3区| 精品国产日韩欧美精品国产欧美日韩一区二区三区| 国产高清精品二区| 日韩欧美一区免费| 国产模特精品视频久久久久| 日韩精品视频在线看| 麻豆国产精品一区二区三区| 久久激情中文| 亚洲人妖在线| 麻豆国产91在线播放| 91精品婷婷色在线观看| 久久性天堂网| 麻豆视频久久| 国产高清一区| 日本午夜精品久久久久| 岛国精品一区| 亚洲精品1区| 国产美女亚洲精品7777| 九色porny丨国产首页在线| 亚洲欧美日韩综合国产aⅴ| 国产精品综合色区在线观看| 日韩福利一区| 中文无码日韩欧| 精品一区二区三区中文字幕视频 | 国产精品美女久久久浪潮软件| 日韩专区视频网站| 国产精品精品| 一区二区高清| 日本不良网站在线观看| 亚洲三级国产| 成人日韩在线| 日韩av一区二区三区四区| 日韩欧美中文| 日韩国产在线一| 久久久久国产精品一区二区| 日本在线不卡视频一二三区| 中文一区一区三区高中清不卡免费| 中文精品在线| 国产成人免费精品| 亚洲制服欧美另类| 黑人精品一区| 欧美影院精品| 99国产精品99久久久久久粉嫩| 精品美女视频 | 亚洲成人一区在线观看| sm捆绑调教国产免费网站在线观看| 日本不卡不码高清免费观看| 欧美精品影院|