如何从eureka获取服务的ip和端口号进行Http的调用
作者:长河 发布时间:2021-07-05 05:28:13
标签:eureka,服务,ip,端口号,Http
eureka获取服务ip和端口号进行Http调用
我告诉你们为啥我要先从eureka首先获取 goods的服务ip, 在用ip的方式使用http调用goods的服务.
因为公司的规定, 不让我们用Feigin. 我TMD的都震惊了, 我都不知道为啥. 我也不想写同事的ip地址, 做配置, 因为都去eureka里面注册了, 所以就这样调用了, 真是蛋疼. 这种微服务, 这种奇葩的方式..
package com.util;
import com.alibaba.fastjson.JSON;
import com.curefun.attendance.appclient.vo.ApplyListVO;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* eureka的工具类
*
* @author zhangke
* @time 2019年12月5日18:11:12
*/
@Slf4j
public class EurekaUtil {
/**
* 解析eureka的返回数据
*/
private static Pattern PATTERN_URL = Pattern.compile("<homePageUrl>(.+?)</homePageUrl>");
/**
* IP的缓存
*/
private static ConcurrentHashMap<String, List<String>> IP_CACHE = new ConcurrentHashMap<>();
/**
* 缓存的名字
*/
private final static String IP_NAME = "goodsIp";
/**
* 获取服务的所有地址(注册在 eureka server 上的服务)
*
* @param eurekaIp
* @return
*/
public static List<String> getAllServiceAddr(String eurekaIp) {
//先查询缓存
List<String> list = IP_CACHE.get(IP_NAME);
if (list != null && list.size() > 0) {
return list;
}
String serviceName = "GOODS";
String url = eurekaIp + "apps/" + serviceName;
OkHttpClient okHttpClient = new OkHttpClient().newBuilder().connectTimeout(2, TimeUnit.SECONDS).build();
Request request = new Request.Builder()
//请求接口 如果需要传参拼接到接口后面
.url(url)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/xml")
.get()
.build();
Response response = null;
List<String> result = new ArrayList<>();
try {
response = okHttpClient.newCall(request).execute();
if (response.isSuccessful()) {
String responseContent = response.body().string();
Matcher matcher = PATTERN_URL.matcher(responseContent);
while (matcher.find()) {
String homepage = matcher.group(1).trim();
result.add(homepage);
}
}
} catch (IOException e) {
log.error("从eureka中查询GOODS的服务实例出错了.原因是 {}", e.getMessage());
return result;
}
IP_CACHE.put(IP_NAME, result);
return result;
}
/**
* GET请求获取列表数据, 同步请求
*
* @param ip
* @param userId
* @param state
* @param pageNo
* @param pageSize
* @param key
* @return
*/
public static List<ApplyListVO> getProductList(String ip, String userId, Integer state, Integer pageNo, Integer pageSize, String key) {
if (StringUtils.isBlank(ip)) {
return Collections.emptyList();
}
StringBuilder sb = new StringBuilder(ip);
sb.append("goods/apply/getStuGoodsApplyList?user_id=").append(userId);
sb.append("&state=").append(state).append("&pageNo=").append(pageNo);
sb.append("&pageSize=").append(pageSize);
if (StringUtils.isNotBlank(key)) {
sb.append("&key=").append(key);
}
long millis = System.currentTimeMillis();
Request request = new Request.Builder().url(sb.toString()).get().build();
OkHttpClient okHttpClient = new OkHttpClient().newBuilder().connectTimeout(2, TimeUnit.SECONDS).build();
try {
Response response = okHttpClient.newCall(request).execute();
if (response.isSuccessful()) {
String string = response.body().string();
//json的转换.换成我需要的实体对象,为空的不返回null, 一个小技巧
List<ApplyListVO> applyListVOS = JSON.parseArray(string, ApplyListVO.class);
if (applyListVOS == null) {
applyListVOS = Collections.emptyList();
}
long millis2 = System.currentTimeMillis();
log.info("从周X那里查询到物资的列表,请求的url是:{},返回结果是:{}", sb.toString(), applyListVOS);
log.info("查询的耗时是(微秒):{}", (millis2 - millis));
return applyListVOS;
} else {
return Collections.emptyList();
}
} catch (Exception e) {
log.error("从周X的接口中查询List信息出错了.原因是 {}", e.getMessage());
return Collections.emptyList();
}
}
}
这样就可以很方便的调用了,
做微服务的一定要协调好各个组件的关系, 不然很容易两个人要对不同的接口, 很麻烦.
对了, 现在我们的eureka 配置有个问题, 就是一个服务挂了之后, 需要很长的时间才能去掉. 然后请求到达网关之后还是去了已经关闭的服务, 就很蛋疼了. 需要配置一个参数.
eureka:
server: #配置属性,但由于 Eureka 自我保护模式以及心跳周期长的原因,
#经常会遇到 Eureka Server 不剔除已关停的节点的问题
enable-self-preservation: false # 设为false,关闭自我保护
eviction-interval-timer-in-ms: 5000 # 清理间隔(单位毫秒,默认是60*1000)启用主动失效,
#并且每次主动失效检测间隔为3s
先要关闭自我保护 enable-self-preservation: false
eviction-interval-timer-in-ms 启用主动失效,并且每次主动失效检测间隔为5s
Eureka Server会定时(间隔值是eureka.server.eviction-interval-timer-in-ms,默认值为0,默认情况不删除实例)进行检查,如果发现实例在在一定时间(此值由客户端设置的eureka.instance.lease-expiration-duration-in-seconds定义,默认值为90s)内没有收到心跳,则会注销此实例。
现在的eureka的配置 已经改过来了。
eureka页面中显示ip+端口
eureka:
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}
# spring.cloud.client.ip-address 为 2.x 版本,1.x 版本为 spring.cloud.client.ipAddress
# ${spring.cloud.client.ip-address} 这个值从 org.springframework.cloud.client.HostInfoEnvironmentPostProcessor 中获取
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
InetUtils.HostInfo hostInfo = getFirstNonLoopbackHostInfo(environment);
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put("spring.cloud.client.hostname", hostInfo.getHostname());
map.put("spring.cloud.client.ip-address", hostInfo.getIpAddress());
MapPropertySource propertySource = new MapPropertySource(
"springCloudClientHostInfo", map);
environment.getPropertySources().addLast(propertySource);
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
来源:https://changhe.blog.csdn.net/article/details/103432215


猜你喜欢
- 首先来看一下效果图:1.编程思路看看界面,不难发现,其就是一个放入九张图片的容器,绘制其实可以在其上面另创建一个透明View负责绘制线与圆圈
- 情况一:配置文件,无法被导出或者生效修改前:修改后:究其原因,这是由于Maven的约定大于配置,导致我们写的配置文件,无法被导出或者生效的问
- 数据库事务是后端开发中不可缺少的一块知识点。Spring为了更好的支撑我们进行数据库操作,在框架中支持了两种事务管理的方式: 编程式事务声明
- 我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用。而ViewPage
- Remote Debug 综述当我们的后台项目部署到服务器上时,由于环境和本地不同,有时候也会有一些奇奇怪怪的问题出现。只依赖服务器上的日志
- 本文为大家分享了C# 7.0中的解构功能,供大家参考,具体内容如下解构元组C#7.0新增了诸多功能,其中有一项是新元组(ValueTuple
- 目录一、什么是Spring二、什么是IOC三、快速搭建框架环境四、spring之依赖注入五、详解Spring框架的IOC之注解方式七、Spr
- 本文实例实现了C#一键换IP、重置DNS、网关及掩码的功能,具体实现的功能为在程序界面窗口中设置ip地址和子网掩码,设置网关地址,设置DNS
- DataGridView 列有三种排序模式。每一列的排序模式是通过该列的 SortMode 属性指定的,该属性可以设置为以下的 DataGr
- 前文简单介绍了Android中SurfaceView的基本使用,本文就来介绍一下SurfaceView与多线程的混搭。SurfaceView
- 本文实例为大家分享了Android studio实现简单计算器的具体代码,供大家参考,具体内容如下话不多说,首先附上代码:MainActiv
- 目前为止,许多编程语言和工具都包含对正则表达式的支持,C#也不例外,C#基础类库中包含有一个命名空间(System.Text.Regular
- 一、LockSupport类的属性private static final sun.misc.Unsafe UNSAFE; &
- 准备工作工具:idea+jdk8技术要求:java基础语法编码环节首先,我们得先确定下来,用什么数据来模拟栈的操作。由于是一个一个的元素放入
- Java数字格式类以下两个类可用于格式化和解析数字:java.text.NumberFormatjava.text.DecimalForma
- 本文实例讲述了C#精确计算年龄的方法。分享给大家供大家参考。具体如下:该源码在vs2010测试通过using System;using Sy
- using System;using System.Collections.Generic;using System.IO;using Sy
- 一、Servlet概述1.sun公司提供的动态web资源开发技术。本质是上一段java小程序,要求这个小程序必须实现Servlet接口,以便
- 效果图如下: Recyclerview 实现多选,单选,全选,反选,批量删除的步骤1.在Recyclerview布局中
- 本文实例为大家分享了Java实现二分查找的变种,供大家参考,具体内容如下普通二分查找:先回顾一下普通的二分查找注意:二分查找有这样一个问题: