微服务 ribbon 不同服务访问,出现访问一个服务,另外一个服务访问不了
问题描述:
有两个不同 服务 A 和 B 调用服务A正常,服务 B 就被挤掉,导致访问服务B 失败,出现404 访问代码如下
/**
* 通过拼接路径访问服务端
* @param ClientName
* @param ClientMoth
* @param object
* @return
*/
@HystrixCommand(fallbackMethod = "PostServicesinfo")
public Object PostServices(String ClientName, String ClientMoth, JSONObject object) {
object.putIfAbsent("FAction",ClientName+"/"+ClientMoth);
//获取服务实例
List<ServiceInstance> list=discoveryClient.getInstances("ClientName");
String uri="";
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> requestEntity = new HttpEntity<String>(JSONObject.toJSONString(object) , requestHeaders);
String url = String.format("http://%s/%s", ClientName, ClientMoth);
//使用注册到Eureka服务中心的客户端,由客户端分配具体调用哪个服务
Object obj =restTemplate.postForObject(url,requestEntity,Object.class);
return obj;
}
找了一下原因后发现,配置出现了问题,配置如下
1.新增俩个配置类型 CloudRole ,RibbonClientConfig

2 CloudRole 配置 设置注解
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.*;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
**
* 该类为Ribbon的配置类
* 注意:该类不应该在主应用程序上下文的@ComponentScan中
*/
@Configuration
public class CloudRole {
/**
* 自定义调用规则(服务提供者掉线后不再调用,解决轮询问题)
* @return
*/
@Bean
public IRule myRule() {
//1、先按照RoundRobinRule(轮询)的策略获取服务,如果获取的服务失败侧在指定的时间会进行重试,进行获取可用的服务
//2、如多次获取某个服务失败,这不会再再次获取该服务如(高德地图上某条道路堵车,司机不会走那条道路)
//return new RetryRule();
//线性轮询
//return new RoundRobinRule();
//可以重试的轮询
//return new RetryRule();
//根据运行情况来计算权重
//return new WeightedResponseTimeRule();
//过滤掉故障实例,选择请求数最小的实例
//return new BestAvailableRule();
return new RandomRule();
}
//IPing
@Bean
public IPing iping() {
return new DummyPing();
}
//服务列表过滤器
@Bean
public ServerListSubsetFilter serverListFilter() {
ServerListSubsetFilter filter = new ServerListSubsetFilter();
return filter;
}
}
3.RibbonClientConfig
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Configuration;
@Configuration
@RibbonClients(defaultConfiguration = CloudRole.class)
public class RibbonClientConfig {
}
4.application.yml 配置
eureka:
client:
serviceUrl:
#defaultZone: http://localhost:8761/eureka/
defaultZone: http://172.172.172.45:8761/eureka/
#请求处理的超时时间 秒
eureka-server-read-timeout-seconds: 6
#请求连接超时时间 秒
eureka-server-connect-timeout-seconds: 5
instance:
lease-expiration-duration-in-seconds: 3
lease-renewal-interval-in-seconds: 5
#lease-renewal-interval-in-seconds 每间隔1s,向服务端发送一次心跳,证明自己依然”存活“
#lease-expiration-duration-in-seconds 告诉服务端,如果我2s之内没有给你发心跳,就代表我“死”了,将我踢出掉。
#设置当前实例的主机名称
hostname: localhost
#部署到别的服务添加
instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
prefer-ip-address: true
5.ServiceRibbonApplication 类配置
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.unit.DataSize;
import org.springframework.web.client.RestTemplate;
import javax.servlet.MultipartConfigElement;
@SpringBootApplication
@EnableDiscoveryClient
//断路器注解
@EnableHystrix
//启动类上加上@EnableCircuitBreaker注解,再次执行上述操作,界面不断输出监控日志。
@EnableCircuitBreaker
//仪表盘注解
@EnableHystrixDashboard
public class ServiceRibbonApplication {
// 实现负载均衡
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
// 设置超时
requestFactory.setConnectTimeout(60000);
requestFactory.setReadTimeout(60000);
//利用复杂构造器可以实现超时设置,内部实际实现为 HttpClient
RestTemplate restTemplate = new RestTemplate(requestFactory);
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ServiceRibbonApplication.class, args);
//new SpringApplicationBuilder(ServiceRibbonApplication.class).web(WebApplicationType.NONE).run(args);
}
//如果都没问题那么检查下springboot 版本如果是2.0则需要添加 ServletRegistrationBean
// 因为springboot的默认路径不是 "/hystrix.stream",
// 只要在自己的项目里配置上下面的servlet就可以了
//仪表盘需要添加此bean
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
/**
* 限制上传文件大小
*/
@Bean
public MultipartConfigElement multipartConfigElement(){
MultipartConfigFactory factory = new MultipartConfigFactory();
//DataSize.parse("5120KB");
//单个文件最大 50m 可以使用读取配置
factory.setMaxFileSize( DataSize.parse("512000KB")); //KB,MB
/// 设置总上传数据总大小 500m
factory.setMaxRequestSize(DataSize.parse("5120000KB"));
return factory.createMultipartConfig();
}
}
欢迎留言 一起学习 一起探讨

浙公网安备 33010602011771号