SpringCloud - 学习笔记
一、SpringCloud简介
SpringCloud是一个基于SpringBoot实现的云应用开发工具,为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、控制总线、全局锁、决策竞选、分布式会话等等。
二、服务注册与发现
Spring Cloud Eureka
Spring Cloud Eureka是Spring Cloud Netflix(Spring Cloud子项目之一)项目下的服务治理模块。主要是对Netfilix公司一系列的开源产品的包装。通过简单的配置,开发者就可以快速在应用中配置常用模块并构建庞大的分布式系统。主要提供的模块: 服务发现(Eureka)、断路器(Hystrix)、智能路由(Zuul)、客户端负载均衡(Ribbon)
-
创建服务注册中心(euraka server)
首先创建一个基础的Spring Boot工程。build.gradle
文件如下:
plugins {
id 'org.springframework.boot' version '2.1.3.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', 'Greenwich.SR1')
}
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// implementation 'org.springframework.cloud:spring-cloud-starter-eureka'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
通过@EnableEurekaServer
注解启动一个服务注册中心,提供给其他应用。
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
在默认情况下,该服务注册中心也会将自己作为客户端来尝试注册自己,所以我们要禁止他的客户端注册行为,需要配置application.yml
文件:
spring:
application:
name: eureka-server
server:
port: 8888
eureka:
instance:
hostname: localhost
client: #设置下面属性为false表明自己是一个 eureka server
register-with-eureka: false
fetch-registry: false
访问localhost:8888
显示内容如下:
-
创建服务提供者(eureka-client)
首先创建一个基础的Spring Boot工程。build.gradle
文件如下:
plugins {
id 'org.springframework.boot' version '2.1.3.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', 'Greenwich.SR1')
}
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
创建/client
请求处理接口,通过DiscoverClient对象,打印出服务实例信息。
@RestController
public class DiscoveryClientController {
@Autowired
DiscoveryClient discoveryClient;
@GetMapping("/client")
public String discoveryClient(){
String services = "Services: " + discoveryClient.getServices();
System.out.println(services);
return services;
}
}
通过@EnableDiscoveryClient
注解,激活Eureka中的DiscoveryClient实现。
@SpringBootApplication
@EnableEurekaClient
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
在application.yml
文件中注明自己的服务注册中心的地址
spring:
application:
name: eureka-client
server:
port: 8000
eureka:
client:
service-url:
defaultZone: http://localhost:8888/eureka/
注:
spring.application.name
属性,指定微服务的名称,后面直接调用该名称就可以进行服务访问。
eureka.client.service-url.defaultZone
对应服务注册中心的配置内容,指定服务注册中心的位置。
启动成功后再次访问localhost:8888
结果如下
当我们访问
eureka-client
中的localhost:8000/client
可以获取当前服务清单:
注:
输出的信息eureka-client
是通过Spring Cloud定义的DiscoveryClient
接口在eureka的实现中获取到的所有清单列表。
三、服务消费者
在Spring Cloud Commons中提供大量的与服务治理相关的抽象接口,包括DidcoveryClient
。这里我们介绍LoadBalancerClient
负载均衡客户端的抽象定义。
创建一个服务消费工程eureka-consumer
plugins {
id 'org.springframework.boot' version '2.1.3.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', 'Greenwich.SR1')
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka', version: '1.4.6.RELEASE'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
配置application.yml文件,指定eureka注册中心地址
spring:
application:
name: eureka-consumer
server:
port: 8100
eureka:
client:
service-url:
defaultZone: http://localhost:8888/eureka/
创建应用主类。初始化RestTemplate,用来真正发起REST其请求。@EnableDiscoveryClient
注解用来将当前应用加入到服务治理体系中。
package com.example.eurekaconsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
public class EurekaConsumerApplication {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(EurekaConsumerApplication.class, args);
}
}
创建一个接口用来消费eureka-client
提供的接口
package com.example.eurekaconsumer.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class ConsumerController {
@Autowired
LoadBalancerClient loadBalancerClient;
@Autowired
RestTemplate restTemplate;
@GetMapping("/consumer")
public String dc() {
ServiceInstance serviceInstance = loadBalancerClient.choose("eureka-client");
String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/client";
System.out.println(url);
return restTemplate.getForObject(url, String.class);
}
}
注:
- 注入
LoadBalancerClient
和RestTemplate
,并在接口中实现。通过LoadBalancerClient
的choose函数来负载均衡选出一个eureka-client
的服务实例。- 服务实例的基本信息存储在
ServiceInstance
中。
最后利用RestTemplate
来调用服务提供者的接口。
通过访问http://localhost:8100/consumer