- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章feign 如何获取请求真实目的ip地址由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
最近小编的项目中出现了很多feign 调用出现 Read Time out 的异常,但因为没有集成链路追踪的第三方框架,查不到原因.
所以想到打印请求的ip地址,判断是指定的服务器出现的问题还是所有服务器都有这个问题,但是feign 打印异常日志不会显示目的端地址,这就很难受了没办法只能自己改装下 。
需要改装肯定需要知道feign 具体请求调用的源码,大致需要知道下面几个问题 。
之前小编有两篇文章分析过 feign相关的源码 。
自定义 feign 调用实现 hystrix 超时、异常熔断 。
Feign 集成 Hystrix实现不同的调用接口不同的设置 。
这其中有个关键的源码位置在于 InvocationHandler 的 invoke 方法,在feign 组件中大致有两个类实现了此接口 。
1
2
|
FeignInvocationHandler
HystrixInvocationHandler
|
如果 项目中使用了 Hystrix 那么会用到HystrixInvocationHandler那个,否则一般是FeignInvocationHandler(自定义组件的除外) 。
那么此时只需要在invoke 方法中打个断点就行 。
此时跟踪到 。
1
|
feign.SynchronousMethodHandler#executeAndDecode
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
Object executeAndDecode(RequestTemplate template)
throws
Throwable {
Request request = targetRequest(template);
.......
Response response;
long
start = System.nanoTime();
try
{
// 真正执行请求
response = client.execute(request, options);
response.toBuilder().request(request).build();
}
catch
(IOException e) {
....
throw
errorExecuting(request, e);
}
.....
}
|
通过debug就知道这个 client 是 。
1
2
|
LoadBalancerFeignClient
org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient#execute
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public
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);
// 封装 ribbon 请求组件
FeignLoadBalancer.RibbonRequest ribbonRequest =
new
FeignLoadBalancer.RibbonRequest(
this
.delegate, request, uriWithoutHost);
IClientConfig requestConfig = getClientConfig(options, clientName);
// 这行是关键
return
// 获取 FeignLoadBalancer
lbClient(clientName)
// 负载之后请求真实的url
// com.netflix.client.AbstractLoadBalancerAwareClient#executeWithLoadBalancer(....)
.executeWithLoadBalancer(ribbonRequest,requestConfig)
.toResponse();
}
catch
(ClientException e) {
....
throw
new
RuntimeException(e);
}
}
|
1
|
com.netflix.client.AbstractLoadBalancerAwareClient#executeWithLoadBalancer(....)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public
T executeWithLoadBalancer(
final
S request,
final
IClientConfig requestConfig)
throws
ClientException {
LoadBalancerCommand<T> command = buildLoadBalancerCommand(request, requestConfig);
try
{
// 在com.netflix.loadbalancer.reactive.LoadBalancerCommand#submit 中会根据 负载均衡算法之后获取到真实的ip地址
return
command.submit(
new
ServerOperation<T>() {
@Override
// 传入的server 就是真实的ip
public
Observable<T> call(Server server) {
URI finalUri = reconstructURIWithServer(server, request.getUri());
// 路径替换把原本 http://client-name/xxxx 地址改为 http://127.0.0.1:9090/xxxx
S requestForServer = (S) request.replaceUri(finalUri);
try
{
// 请求父类中的 execute 方法,也就是 上面 lbClient(clientName) 返回的 FeignLoadBalancer
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);
}
}
}
|
1
|
org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer#execute
|
1
2
3
4
5
6
7
8
9
10
11
|
@Override
public
RibbonResponse execute(RibbonRequest request, IClientConfig configOverride)
throws
IOException {
Request.Options options;
.....
// 这里的 request 就是 `org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient#execute`
// 封装的FeignLoadBalancer.RibbonRequest
// request.client() 返回就是 feign.Client.Default
Response response = request.client().execute(request.toRequest(), options);
return
new
RibbonResponse(request.getUri(), response);
}
|
1
|
feign.Client.Default#execute
|
1
2
3
4
5
|
@Override
public
Response execute(Request request, Options options)
throws
IOException {
HttpURLConnection connection = convertAndSend(request, options);
return
convertResponse(connection).toBuilder().request(request).build();
}
|
这里的request 中 url 就是真实的url资源路径了 。
现在屡屡逻辑 。
1
|
org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient和feign.Client.Default
|
都实现了 feign.Client 接口,但是 LoadBalancerFeignClient 实际上调用的还是 feign.Client.Default,无非做了自己处理(负载),有些类似于静态代理 。
那么上面的问题就只剩下能否替换的问题了 。
1
2
3
4
5
6
7
8
9
10
|
@Configuration
class
DefaultFeignLoadBalancedConfiguration {
@Bean
@ConditionalOnMissingBean
public
Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory) {
return
new
LoadBalancerFeignClient(
new
Client.Default(
null
,
null
),
cachingFactory, clientFactory);
}
}
|
这就不需要我来过多解释了,我们只需要自定义一个 LoadBalancerFeignClient 或者 实现Client的类就行 然后注入就行 。
我选择的是 自定义实现一个 Client,去继承 feign.Client.Default 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@Slf4j
public
class
InFeignClient
extends
Client.Default {
/**
*/
public
InFeignClient(SSLSocketFactory sslContextFactory, HostnameVerifier hostnameVerifier) {
super
(sslContextFactory, hostnameVerifier);
}
@Override
public
Response execute(Request request, Request.Options options)
throws
IOException {
try
{
return
super
.execute(request, options);
}
catch
(IOException e) {
log.warn(
" 请求 {} 异常 ======> {}"
, request.url(), e.getMessage());
throw
e;
}
}
}
|
然后将这个类替换 。
1
2
3
4
5
6
7
8
9
10
11
12
|
@Component
public
class
RestConfig {
public
CachingSpringLoadBalancerFactory cachingLBClientFactory(
SpringClientFactory factory) {
return
new
CachingSpringLoadBalancerFactory(factory);
}
@Bean
public
Client feignClient(SpringClientFactory clientFactory) {
CachingSpringLoadBalancerFactory bean = cachingLBClientFactory(clientFactory);
return
new
LoadBalancerFeignClient(
new
InFeignClient(
null
,
null
), bean, clientFactory);
}
}
|
原文链接:https://blog.csdn.net/weixin_39660224/article/details/115397061 。
最后此篇关于feign 如何获取请求真实目的ip地址的文章就讲到这里了,如果你想了解更多关于feign 如何获取请求真实目的ip地址的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
目前,我有以下设置: A记录: mydomain.com - aaa.aaa.aaa.aaa subdomain.mydomain.com - aaa.aaa.aaa.aaa NS记录: mydoma
有人可以帮助我以最佳方式在流畅的 nHibernate 中映射以下情况吗? Address 类用于 Client 和 Company。如何在 SQL 中最有效地存储它?映射应该是什么样的?我已经考虑过
我正在尝试编写一个 Windows 应用程序,它将在来自 PC 的以太网链接上生成流量。 我想使用 webBrowser 控件不断拉取网页以产生流量。 在这种情况下,我希望每个 webBrowser
我正在编写一个 SIP 堆栈,我需要在消息中插入一个 IP 地址。该地址必须是用于发送消息的地址。我知道目标 IP 并且需要确定将用于发送消息的 NIC(其地址).... 最佳答案 为了扩展 Remy
如何使用 IP 地址获取 MAC 地址,但以下代码不起作用 packet = ARP(op=ARP.who_has,psrc="some ip",pdst = ip) response = srp(p
目前我想知道如何实现对本地无线网络(路由器)的获取请求以获取当前连接到当前连接的 LAN 的所有设备.... 所以我做了一些研究,显然“nmap”是一个终端/命令提示符命令,它将连接的设备返回到本地无
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicates: how to find MAC address in MAC OS X programmatically
我们正在为 ipad 开发一个 iOS 应用程序,它使用 bonjour 与其他设备连接,使用 couchbaseListener 与对等数据库进行复制。我们观察到,每当 [nsnetservice
我创建了 3 个实例,其中 3 个弹性 IP 地址指向这些实例。 我做了 dsc 的 yum 安装:dsc12.noarch 1.2.13-1 @datastax 并且/etc/cassandra/d
我正在尝试获取规模集中所有虚拟机的私有(private) IP 地址列表(没有一个虚拟机故意拥有任何公共(public) IP 地址)。我找到了如何从 az cli 获取此内容,如下所示: az vm
我正在尝试获取规模集中所有虚拟机的私有(private) IP 地址列表(没有一个虚拟机故意拥有任何公共(public) IP 地址)。我找到了如何从 az cli 获取此内容,如下所示: az vm
我正在尝试与该端口上的任何 IP 建立连接。最初,我将其设置为 10.0.0.7,这是我网络上另一台计算机的 IP,因此我可以测试客户端/服务器。但是,我希望它可以与任何计算机一起使用而不必将 IP
作为序言,我开发了自己的 CRM(类似于 SalesForce 或 SAP),其“规模”要小得多,因为它面向服务,而不是销售。我在 Ubuntu 16.04 服务器上使用 MySql 或 MariaD
在我的项目中,我想做如下事情: static void test0(void) { printf("%s [%d]\n", __func__, __LINE__); } static void
我的机器上有两个网卡,配置了两个独立的 IP 地址。两个 IP 地址都属于同一个网络。我是否正确地说,当我创建一个特定于这些 IP 地址之一的套接字时? 更新: 这是我的情况: 我有一个位于 192.
当然,我意识到没有一种“正确的方法”来设计 SQL 数据库,但我想就我的特定场景中的优劣获得一些意见。 目前,我正在设计一个订单输入模块(带有 SQL Server 2008 的 Windows .N
我们将保存大量地址数据(在我公司的眼中,每个客户大约有150.000至500.000行)。 地址数据包含约5列: 名称1 名称2 街(+否) 邮政编码 市 也许以后再添加一些东西(例如电话,邮件等)
好的,我们在生产中实现了 Recaptcha。我们收到错误是因为它无法到达使用该服务所需的 IP 地址。我们为 IP 地址打开一个端口以到达 Google。没问题。我们这样做并显式配置该 IP 地址以
此页面使用 Drupals 联系表发送电子邮件:http://www.westlake.school.nz/contact 问题是,学校员工使用 outlook。当他们收到来自 parent 等的电子
是否可以将用户输入的邮政编码转换为文本框并将其转换为CLLocation?我正在尝试比较其当前位置与地址或邮政编码之间的距离,如果可以从NSString中创建CLLocation,这将很容易。 最佳答
我是一名优秀的程序员,十分优秀!