eureka服务端注册中心(打开浏览器,输入http://localhost:8761/,就可以看到Eureka注册情况):
谁注册了谁就可以对外提供Eureka接口
server: port: 8761 eureka: client: #由于该应用为注册中心,所以设置为false,代表不向注册中心注册自己 registerWithEureka: false #由于注册中心的职责就是维护服务实例,它并不需要去检索服务,所以也设置为false fetchRegistry: false serviceUrl: defaultZone: http://localhost:8761/eureka/
clientA 发起注册
server: port: 8001 spring: application: name: eureka-provider-A #服务发现客户端 eureka: instance: #向Eureka注册时,是否使用IP地址+端口号作为服务实例的唯一标识。推荐设置为true prefer-ip-address: true client: #是否将自身的实例信息注册到Eureka服务端 register-with-eureka: true #是否拉取并缓存其他服务注册表副本到本地 fetch-registry: true # eureka client刷新本地缓存时间 registryFetchIntervalSeconds: 5 #注册到哪个Eureka服务实例 service-url: defaultZone: http://localhost:8761/eureka/
clientB 发起注册
server: port: 8002 spring: application: name: eureka-provider-B #服务发现客户端 eureka: instance: #向Eureka注册时,是否使用IP地址+端口号作为服务实例的唯一标识。推荐设置为true prefer-ip-address: true client: #是否将自身的实例信息注册到Eureka服务端 register-with-eureka: true #是否拉取并缓存其他服务注册表副本到本地 fetch-registry: true # eureka client刷新本地缓存时间 registryFetchIntervalSeconds: 5 #注册到哪个Eureka服务实例 service-url: defaultZone: http://localhost:8761/eureka/
eureka服务调用:clientA调用clientB的接口
@EnableFeignClients //必须1 @EnableDiscoveryClient //必须2 @SpringBootApplication public class EurekaDemoConsumer { public static void main(String[] args) { SpringApplication.run(EurekaDemoConsumer.class, args); } }
@FeignClient("ueh-organization") public interface OrganizationClient { @GetMapping("/organization/{organizationId}") R<OrganizationDTO> getOrganization(@PathVariable("organizationId") Long organizationId); }
调用方式1: github: spring-cloud-advance
{ @Autowired private OrganizationClient organizationClient; public LicenceDTO queryDetail(Long licenceId) { Licence licence = this.getById(licenceId); // 校验非空 ResponseEnum.LICENCE_NOT_FOUND.assertNotNull(licence); OrganizationDTO org = ClientUtil.execute(() -> organizationClient.getOrganization(licence.getOrganizationId())); return toLicenceDTO(licence, org); } }
// 远程调用工具类 public class ClientUtil { /** * 封装远程调用, 只返回关心的内容 * @param supplier 远程调用真正逻辑, 返回内容为: {@link R<T>} * @param <T> 关心的内容类型 * @return 关心的内容 */ public static <T> T execute(Supplier<R<T>> supplier) { R<T> r = supplier.get(); CommonResponseEnum.assertSuccess(r); return r.getData(); } /** * 封装远程调用, 只返回关心的内容 * @param supplier 程调用真正逻辑, 返回内容为: {@link QR<T>} * @param <T> 关心的内容类型 * @return 关心的内容 */ public static <T> QueryData<T> executePage(Supplier<QR<T>> supplier) { QR<T> qr = supplier.get(); CommonResponseEnum.assertSuccess(qr); return qr.getData(); } }
调用方式2: https://www.jianshu.com/p/8e1f4cccee33
服务发现与负载均衡(Ribbon + RestTemplate)
定义RestTemplate,结合Ribbon可以实现客户端负载均衡 @Configuration public class EurekaDemoConfiguration { //LoadBalanced 基于ribbon进行负载均衡 @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } } @RestController public class GreetingController { @Autowired RestTemplate restTemplate; @RequestMapping(value = "/greeting/{name}", method = RequestMethod.GET) public String greeting(@PathVariable("name") String name) { //使用restTemplate发送http请求 return restTemplate.getForObject("http://eureka-provider-B/organization/sayHello/" + name, String.class); } }
clientB端Controller
@RequestMapping("/organization") @RestController public class OrganizationController { @Autowired private OrganizationService organizationService; @GetMapping("/{organizationId}") public R<OrganizationDTO> getOrganization(@PathVariable("organizationId") Long organizationId) { return new R<>(organizationService.queryDetail(organizationId)); } @RequestMapping(value = "/sayHello/{name}", method = RequestMethod.GET) public String sayHello(@PathVariable("name") String name) { return "hello," + name; } }