SpringCloud简单梳理

SpringCloud

Eureka

eureka是一个服务注册/发现的东西,分为服务端和客户端;

Eureka单机服务端的搭建

用STS创建一个SpringBoot项目,启动器选择web模块和SpringCloud Discovery中的Eureka Server;

在启动类上加上@EnableEurekaServer的注解,表明此应用是一个Eureka Server

package com.springcloud.EurekaServer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaServerApplication.class, args);
	}

}

yml配置:

#eureka默认端口8761,这里开启web端口,建议与默认端口一致
server: 
  port: 8761

#为spring应用定义一个唯一名称,默认是null
#SpringCloud中的微服务,同命名的自动形成集群
spring: 
  application:
    name: eureka-server
    

# eureka配置
eureka:
  client:
    register-with-eureka: false #是否注册本服务,默认是true
    fetch-registry: false #是否发现其他服务,默认是true

此处为何将服务注册和发现都设为false呢?

默认都是true的,但是由于此处搭建的是一个单机版,也就是说,服务本身如果被服务本身发现注册的话会形成死循环;

我们在浏览器输入localhost:8761即可进入eureka服务端可视化页面;

Eureka集群服务端的搭建

我们再多配两个配置文件,启动的时候只要根据不同配置文件启动SpringBoot实例即可;

application-eureka1.yml:

server: 
  port: 8761

spring:
  application:
    name: eureka-server

eureka:
  client:
    service-url:
      defaultZone: http://192.168.24.7:8761/eureka/ #表示当前服务注册到哪一个注册中心
  instance: 
    prefer-ip-address: true #使用ip注册不使用主机名注册

application-eureka2.yml:

server: 
  port: 8761

spring:
  application:
    name: eureka-server

eureka:
  client:
    service-url:
      defaultZone: http://192.168.24.8:8761/eureka/ #表示当前服务注册到哪一个注册中心
  instance: 
    prefer-ip-address: true #使用ip注册不使用主机名注册

这两个就是到哪儿注册变了一下,其他一样;

我们把项目打包,传到服务器上,分别按不同的配置文件启动jar:

java -jar -Dspring.profiles.active=eureka1 eureka.jar;

java -jar -Dspring.profiles.active=eureka2 eureka.jar;

然后当我们访问192.168.24.7:8761192.168.24.8:8761会发现DS Replicas中有了彼此,这就代表他们俩是一个集群了;

Ribbon

ribbon主要做的是客户端的负载均衡;

服务的提供方

无论是服务的提供方还是消费方,他们都是服务,也就是说,他们都是eureka的客户端,需要到eureka注册中心注册发现;

所以我们先启动eureka的服务端,这里就以单机版为例;

用STS创建Springboot项目,启动器选择Web和SpringCloud Discovery中的Eureka Discovery Client;

没错,不需要引入任何Ribbon相关的依赖,eureka是不知道ribbon的存在的;

假设我们提供的服务是插入一个用户:

package com.springcloud.RibbonServer.pojo;

public class User {
	private String name;
	private Integer age;
	private String remark;
	private String job;
	public User() {
		// TODO Auto-generated constructor stub
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getRemark() {
		return remark;
	}
	public void setRemark(String remark) {
		this.remark = remark;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + ", remark=" + remark + ", job=" + job + "]";
	}
	
}

controller:

package com.springcloud.RibbonServer.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.springcloud.RibbonServer.pojo.User;

@RestController
public class UserController {

	@RequestMapping("/insert")
	public Map<String,Object> insertUser(User u){
		System.out.println("正在新增用户:"+u);
		Map<String,Object> result = new HashMap<String, Object>();
		result.put("code",200);
		result.put("message","新增用户成功");
		return result;
	}
}

最关键的配置文件来了:

server:
  port: 8080
  
spring:
  application:
    name: ribbon-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/ #到这个注册中心去注册,如果有多个注册中心的话(集群),可以用逗号分隔

可以看到,我们需要到eureka服务端注册一哈;

启动应用,进入http://localhost:8761,你会发现eureka已经将此服务注册了。

很简单吧,其实什么也不用做,就导一下Client的依赖,再在配置文件里指定一下eureka注册中心即可,其他的跟以前写代码一样;

服务的消费方

说白了就是调用我们上面写的方法,一个http请求;

一般我们会将远程调用的过程放到Service中;

按照上面的办法新建一个项目作为服务的消费方;

controller

package com.springcloud.RibbonClient.controller;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.springcloud.RibbonClient.pojo.User;
import com.springcloud.RibbonClient.service.UserService;

@RestController
public class UserController {

	@Autowired
	private UserService userService;
	
	@RequestMapping("/insert")
	public Map<String,Object> insertUser(User u) {
		Map<String,Object> result = userService.insertUser(u);
		System.out.println("远程调用返回的结果:"+result);
		return result;
	}
}

service:

package com.springcloud.RibbonClient.service.impl;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.springcloud.RibbonClient.pojo.User;
import com.springcloud.RibbonClient.service.UserService;

@Service
public class UserServiceImpl implements UserService {

	/**
	 * 这是Ribbon技术中的负载均衡客户端对象,封装了 从eureka server中发现的所有服务的地址列表 包括了服务的IP,端口,名称
	 */
	@Autowired
	private LoadBalancerClient loadBalancerClient;

	/**
	 * 这里面调用远程方法
	 */
	@Override
	public Map<String, Object> insertUser(User u) {
		// 获取一个服务实例,参数是服务名称
		ServiceInstance instance = loadBalancerClient.choose("ribbon-service");
		// 拼接url
		StringBuilder sb = new StringBuilder();
		sb.append("http://").append(instance.getHost()).append(":").append(instance.getPort()).append("/insert?name=")
				.append(u.getName()).append("&age=").append(u.getAge()).append("&remark=").append(u.getRemark())
				.append("&=job").append(u.getJob());

		// 发送http请求

		// 创建rest模板对象,用于发送http请求
		RestTemplate template = new RestTemplate();
		// 约束响应类型
		ParameterizedTypeReference<Map<String, Object>> responseType = new ParameterizedTypeReference<Map<String, Object>>() {
		};

		/*
		 * 四个参数; 1.url 2.请求方法 3.请求实体 4.响应类型
		 */
		ResponseEntity<Map<String, Object>> response = template.exchange(sb.toString(), HttpMethod.GET, null,
				responseType);
		Map<String, Object> result = response.getBody();
		return result;
	}
}

配置文件:

server:
  port: 8081
  
spring:
  application:
    name: ribbon-client
    
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

配置文件就是端口变一下,名字变一下,其他基本都一样的。

负载均衡策略

网上找了一张表,介绍了Ribbon的负载均衡策略:

策略类命名描述
RandomRule随机策略随机选择server
RoundRobinRule轮询策略按照顺序选择server(ribbon默认策略)
RetryRule重试策略在一个配置时间段内,当选择server不成功,则一直尝试选择一个可用的server
BestAvailableRule最低并发策略逐个考察server,如果server断路器打开,则忽略,再选择其中并发链接最低的server
AvailabilityFilteringRule可用过滤策略过滤掉一直失败并被标记为circuit tripped的server,过滤掉那些高并发链接的server(active connections超过配置的阈值)
ResponseTimeWeightedRule响应时间加权重策略根据server的响应时间分配权重,响应时间越长,权重越低,被选择到的概率也就越低。响应时间越短,权重越高,被选中的概率越高,这个策略很贴切,综合了各种因素,比如:网络,磁盘,io等,都直接影响响应时间
ZoneAvoidanceRule区域权重策略综合判断server所在区域的性能,和server的可用性,轮询选择server并且判断一个AWS Zone的运行性能是否可用,剔除不可用的Zone中的所有server

比如我想使用随机策略,我就可以按如下方法配置:

server:
  port: 8081
  
spring:
  application:
    name: ribbon-client
    
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

      
#负载均衡配置
#最高级写你要远程调用的服务的名称
ribbon-service: 
  ribbon: 
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #使用随机策略

前缀com.netflix.loadbalancer都是一样的,不同的负载均衡策略只要根据上表改一下后缀就行了。

OpenFeign

从上面Ribbon的代码中可以看出,远程调用其他服务的代码很繁琐,OpenFeign对于Ribbon进行了进一步的封装,使得我们在调用远程服务时更加便捷;

服务的提供方

在使用Feign的过程中,我们需要一个接口来约束服务的消费方和提供方,接口如下:

package com.springcloud.FeignService.api;
/**
 * 约束服务的提供者和消费者:
 * 包括需要提供什么服务,允许访问什么服务,服务访问路径等;
 * 注意,普通类型参数需要加上注解@RequestParam,自定义类型参数需要加上注解@RequestBody
 *
 */

import java.util.Map;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import com.springcloud.FeignService.pojo.User;

public interface UserServiceApi {

	@PostMapping("/insert")
	Map<String,Object> insert(@RequestBody User user);
}

我们让服务提供方的controller继承这个接口,这样便受到了此接口的约束:

package com.springcloud.FeignService.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.web.bind.annotation.RestController;

import com.springcloud.FeignService.api.UserServiceApi;
import com.springcloud.FeignService.pojo.User;

@RestController
public class UserController implements UserServiceApi{

	@Override
	public Map<String, Object> insert(User user) {
		Map<String,Object> result = new HashMap<String, Object>();
		result.put("message", "新增用户成功");
		return result;
	}
}

其他地方就没什么不一样的了,配置文件也没什么不同,还是要到eureka里面注册。

服务的消费方

在服务的消费方中,我们要使用OpenFeign调用远程服务,所以需要其依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

controller

package com.springcloud.FeignClient.controller;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.springcloud.FeignClient.pojo.User;
import com.springcloud.FeignClient.service.UserService;

@RestController
public class UserController {
	@Autowired
	private UserService userService;
	
	@GetMapping("/insert")
	public Object insert(User u) {
		Map<String,Object> result =  userService.insert(u);
		System.out.println(result);
		return result;
	}
}

service:

package com.springcloud.FeignClient.service;

import org.springframework.cloud.openfeign.FeignClient;

import com.springcloud.FeignClient.api.UserServiceApi;
/**
 * 
 * 本地服务,用于访问远程服务,和远程服务同受到UserServiceApi的约束
 * 只需添加@FeignClient("远程服务名")即可
 *
 */
@FeignClient("feign-service")
public interface UserService extends UserServiceApi{

}

注意我们不需要写实现类,只要添加这一个注解就够了。

为了让能扫描到@FeignClient注解,我们还需要在启动类上添加注解@EnableFeignClients

package com.springcloud.FeignClient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class FeignClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeignClientApplication.class, args);
    }

}

配置文件依旧没有什么变化。

压缩配置

数据的压缩分为两块,OpenFeign内部的压缩(服务提供方与消费方间的数据压缩)和全局的压缩(包括了浏览器与服务消费者间的数据压缩),一般我们都会对文本文件进行压缩。

配置文件如下:

server:
  port: 8081
  compression: #开启全局压缩
    enabled: true
    mime-types: 
      - text/html
      - text/plain
      - text/xml
      - application/json
      - application/xml
      - application/javascript
    min-response-size: 512
  
spring:
  application:
    name: feign-client

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

#feign开启数据压缩
feign: 
  compression: 
    request: 
      enabled: true #开启请求gzip压缩
      mime-types: 
        - text/html
        - text/plain
        - text/xml
        - application/json
        - application/xml
        - application/javascript
      min-request-size:  512 #数据大小超过这个阈值就开启压缩,默认是2048字节
    response: 
      enabled: true #开启响应gzip压缩

超时与负载均衡配置

先说负载均衡吧,跟ribbon的配置一模一样,因为OpenFeign底层就是调用的Ribbon:

#最上级代表服务提供方的服务名
feign-service: 
  ribbon: 
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #使用随机策略

超时配置如下:

ribbon: 
  ConnectTimeout: 1000 #默认连接超时时间 1秒
  ReadTimeout: 1000 #默认处理超时时间 1秒 且必须大于等于连接超时时间

这个可能会出问题,因为ribbon和feign的ribbon版本冲突,所以我们可以直接这样配置:

feign: 
  client:
    config:
      default:
        connect-timeout: 5000 #连接超时时间,原先默认的是1秒
        read-timeout: 5000 #处理超时时间,原先默认也是1秒,注意这个值必须大于等于来能接超时时间

Hystrix

hystrix主要用来做服务的降级和熔断。

启动器:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

Ribbon下的服务降级

这里就以最简单的sleep模拟服务提供方处理超时。

ribbon默认是没有超时时间的,但是加了hystrix之后我们就可以返回一个托底数据,避免用户等待时间过长。

@Override
@HystrixCommand(fallbackMethod = "insertFallback")
public Map<String, Object> insertUser(User u) {
    // 获取一个服务实例,参数是服务名称
    ServiceInstance instance = loadBalancerClient.choose("ribbon-service");
    // 拼接url
    StringBuilder sb = new StringBuilder();
             sb.append("http://").append(instance.getHost()).append(":").append(instance.getPort()).append("/insert?name=").append(u.getName()).append("&age=").append(u.getAge()).append("&remark=").append(u.getRemark()).append("&=job").append(u.getJob());

    // 发送http请求

    // 创建rest模板对象,用于发送http请求
    RestTemplate template = new RestTemplate();
    // 约束响应类型
    ParameterizedTypeReference<Map<String, Object>> responseType = new ParameterizedTypeReference<Map<String, Object>>() {
    };

    /*
		 * 四个参数; 1.url 2.请求方法 3.请求实体 4.响应类型
		 */
    ResponseEntity<Map<String, Object>> response = template.exchange(sb.toString(), HttpMethod.GET, null,
                                                                     responseType);
    Map<String, Object> result = response.getBody();
    return result;
}

private Map<String,Object> insertFallback(User u){
    Map<String,Object> map = new HashMap<String, Object>();
    map.put("message", "服务器繁忙,请稍后重试");
    return map;
}

我们只要在调用远程方法的方法中添加注解@HystrixCommand(fallbackMethod = "insertFallback")

fallbackMethod里面填写服务降级后调用的本地方法名称,然后写一个本地方法即可。

为了扫描这个注解,我们还需要在启动类上添加一个注解:@EnableCircuitBreaker;

Ribbon下的服务熔断

熔断就是说我判断这个远程服务出问题了,一段时间之内不再调用它了,直接返回托底数据,还是在@HystrixCommand注解里面配置,具体配置如下:

/**
	 * HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,单位时间内多少请求发生错误开启熔断;
	 * HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE,单位时间内,请求发生错误的百分比达到多少,开启熔断;
	 * HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,熔断后多少毫秒之内不再访问远程服务;
	 */
@HystrixCommand(fallbackMethod = "insertFallback",commandProperties = {
    @HystrixProperty(
        name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,
        value = "10"),
    @HystrixProperty(
        name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE,
        value = "50"),
    @HystrixProperty(
        name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,
        value = "4000")
})

OpenFeign下的服务降级

首先我们需要开启OpenFeign下的Hystrix:

feign: 
  hystrix:
    enabled: true #开启hystrix降级处理

后面的事就很简单了,我们不是有这个嘛:

package com.springcloud.FeignClient.service;

import org.springframework.cloud.openfeign.FeignClient;

import com.springcloud.FeignClient.api.UserServiceApi;
import com.springcloud.FeignClient.service.impl.UserServiceImpl;
/**
 * 
 * 本地服务,用于访问远程服务,和远程服务同受到UserServiceApi的约束
 * 只需添加@FeignClient("远程服务名")即可
 *
 */
@FeignClient(value = "feign-service",fallback = UserServiceImpl.class)
public interface UserService extends UserServiceApi{

}

配置fallback为该接口的实例,该接口里面重写的方法即为降级后的方法:

package com.springcloud.FeignClient.service.impl;

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.springcloud.FeignClient.pojo.User;
import com.springcloud.FeignClient.service.UserService;
@Service
public class UserServiceImpl implements UserService{

	@Override
	public Map<String, Object> insert(User user) {
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("message", "进入fallback方法啦!");
		return map;
	}

}

这样就算是写好了。

OpenFeign下的服务熔断

跟Ribbon不一样,feign下做熔断不用写注解,直接在yml里面配置就可以,但是配置的时候可能没有代码提示,但是不影响最终效果;

#配置hystrix熔断
hystrix: 
  command: 
    default: 
      execution: 
        timeout: 
          enable: true
        isolation: 
          thread: 
            timeoutInMilliseconds: 4000
      circuitBreaker: #熔断服务相关配置
        enable: true #开启熔断服务
        requestVolumeThreshold: 3 #单位时间内错误多少次开启熔断
        sleepWindowInMilliSeconds: 3000 #熔断后多少毫秒不访问远程服务
        errorThresholdPercentage: 20 #单位时间内错误百分比达到多少开启熔断
        forceOpen: false #是否强制开启熔断,也就是熔断后再也不访问远程服务,默认就是false
        forceClosed: false #是否强制关闭熔断,默认false

Config

config是SpringCloud的配置中心,用来管理配置文件。这是由于微服务项目每个服务都有一个配置文件,配置太多太杂,于是由配置中心统一管理比较方便。

远程仓库准备

我们把yml都放到远程仓库中,以后每一个配置文件都从远程获取即可。

Gitee或者GitHub都可以。

注意命名,例如feign-service-dev.yml,他就是代表dev环境的feign-service配置文件。

配置中心服务端

配置中心的服务端也作为一个eureka客户端,因此需要eureka客户端的启动器,还需要config服务端的启动器:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

在启动类上添加注解@EnableConfigServer:

package com.springcloud.Config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableConfigServer
public class ConfigApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConfigApplication.class, args);
	}

}

其配置文件如下:

server:
  port: 8888 #默认端口就是这个
  
spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/muziliuri/cloud-config.git
#          如果是私有仓库的话,还需要用户名和密码
#          username: 远程仓库的用户名
#          password: 远程仓库的密码

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

我们可以这样测试一下:

http://localhost:8888/feign-service/default/master

这个url请求了我在gitee仓库中的feign-service.yml配置文件,返回的json数据如下:

{
    "name":"feign-service",
    "profiles":[
        "default"
    ],
    "label":"master",
    "version":"bd8c5da0f52510b8a1512b2ad9f0d862d6d45a86",
    "state":null,
    "propertySources":[
        {
            "name":"https://gitee.com/muziliuri/cloud-config.git/feign-service.yml",
            "source":{
                "server.port":8080,
                "spring.application.name":"feign-service",
                "eureka.client.service-url.defaultZone":"http://localhost:8761/eureka/"
            }
        }
    ]
}

如果我们需要请求feign-service-dev.yml配置文件,相应的url应该改为:

http://localhost:8888/feign-service/dev/master

配置中心客户端

首先我们要导入客户端的依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

然后我们由于是从远程仓库中获取配置文件,那么原来的配置文件就不需要了。

我们新建一个配置文件:bootstrap.yml,必须是这个名字,这个配置文件的优先级是大于application.yml的,我们在里面进行如下配置:

spring:
  cloud:
    config:
      uri: http://localhost:8888/ #默认访问地址
      name: feign-service  #配置文件名称
      profile: default #配置文件默认环境,默认就是default
      label: master #访问地址默认分支,默认就是master

这样就可以了。

Gateway

网关就是相当于Nginx,微服务相当于Tomcat,我们在Gateway中统一配置进行路径转发。此处有个天坑就是Gateway版本必须与服务的提供者以及消费者保持一致,无论是SpringBoot还是SpringCloud,不然会容易出问题。

简单使用

首先是依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

要注意的是Gateway中不能有web依赖,否则会有冲突,启动不了。

配置文件:

server:
  port: 9999
  
spring:
  application:
    name: gateway
  cloud: 
    gateway:
      enabled: true # 开启网关功能,默认就是开启的
      discovery: # 网关发现机制配置信息
        locator:
          enabled: true # 开启网关发现机制
          lower-case-service-id: true # 发现的服务命名是否要转化为小写
      routes: #配置路由
        - id: feign-client #命名随意,唯一即可
          uri: lb://feign-client #lb代表loadbalance,feign-client代表要转发的服务名
          predicates: # 断言机制
            - Path=/test/** #将http://localhost:9999/test/**进行转发,转发至http://feign-client的ip端口/test/**
          filters: 
            - StripPrefix=1 #过滤1个单位的前缀,就是将http://feign-client的ip端口/test/**过滤为http://feign-client的ip端口/**

eureka: 
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

routes这一段是手工配置,其实我们也可以不配,通过服务名来访问服务:

http://localhost:9999/feign-client/**

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值