1. Today's Content
- Introduction to Spring Cloud
- Spring Cloud Service Governance
2. Introduction to Spring Cloud
2.1 Microservices Architecture
![1587520885330]
Microservices Architecture: The term "microservices" originated from Martin Fowler's blog post titled "Microservices", which can be found on his official blog: http://martinfowler.com/articles/microservices.html
-
Microservices is a design style in system architecture. Its main idea is to break down a single, independent system into multiple small services, each running in its own process. These services communicate with each other, typically using HTTP RESTful APIs.
-
Each small service is built around a specific business function or a set of highly coupled business functions within the system. Each service maintains its own data storage, business development, automated test cases, and independent deployment mechanisms.
-
Due to the lightweight communication foundation, thece microservices can be written in different programming languages.
![1587521016035]
2.2 Introduction to Spring Cloud
![1587521103729]
-
Spring Cloud is an ordered collection of frameworks.
-
Spring Cloud does not reinvent the wheel. It simply combines the mature and battle-tested service frameworks developed by various companies.
-
By re-packaging in the Spring Boot style, it hides complex configurations and implementation details, providing developers with an easy-to-understand, easy-to-deploy, and easy-to-maintain distributed system development toolkit.
-
It leverages the development convenience of Spring Boot to gracefully simplify the development of distributed system infrastructure, such as service discovery and registration, configuration center, message bus, load balancing, circuit breaker, data monitoring, etc. These can all be started and deployed with a single click using the Spring Boot development style.
-
Official Spring Cloud project website: https://spring.io/projects/spring-cloud
-
Spring Cloud version naming uses London Underground station names, ordered alphabetically by release time. For example: the earliest Release version: Angel, the second Release version: Brixton, followed by Camden, Dalston, Edgware, Finchley, Greenwich, Hoxton.
-
The latest version is Hoxton.
![1587521364642]
2.3 Comparison of Spring Cloud and Dubbo
![1587521416722]
Comparison of Spring Cloud and Dubbo
-
Both Spring Cloud and Dubbo are effective tools for implementing microservices.
-
Dubbo only implements service governance, while the Spring Cloud sub-projects cover many components of the microservices architecture.
-
Dubbo uses the RPC communication protocol, while Spring Cloud uses RESTful communication. Dubbo is slightly more efficient than Spring Cloud.
Summary
-
Microservices is an architectural design style that splits project modules into independently runnable, deployable, and testable components.
-
Spring Company integrates common microservices architecture components from other companies and uses Spring Boot to simplify their development and configuration. This integration is called Spring Cloud.
-
Both Spring Cloud and Dubbo are effective tools for implementing microservices. Dubbo has better performance, but Spring Cloud is more comprehensive in functionality.
3. Spring Cloud Service Governance
3.1 Introduction to Eureka
-
Eureka is a service registration and discovery component open-sourced by Netflix.
-
Eureka, along with other Netflix service components (such as load balancing, circuit breaker, gateway, etc.), is integrated into the Spring-Cloud-Netflix module by the Spring Cloud community.
-
Eureka consists of two components: Eureka Server (registry) and Eureka Client (service provider, service consumer).
![1587521790834]
Eureka Learning Steps
- Build Provider and Consumer services.
- Use RestTemplate for remote calls.
- Build an Eureka Server service.
- Transform Provider and Consumer into Eureka Clients.
- The Consumer service completes remote calls by fetching the Provider address from the Eureka Server.
3.2 Eureka Quick Start
3.2.1 Environment Setup
![1587521884457]
3.2.1.1 Create Parent Project
Create a module - parent project spring-cloud-parent
![1587522395375]
- Directory structure after creation (delete src)
![1587522452309]
pom.xml for spring-cloud-parent:
<!--spring boot environment -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
3.2.1.2 Create Service Provider
- Create service provider
eureka-provider
![1587522728754]
pom.xml for eureka-provider:
<dependencies>
<!--spring boot web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
GoodsController:
package com.itheima.provider.controller;
import com.itheima.provider.domain.Goods;
import com.itheima.provider.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Goods Controller - Service Provider
*/
@RestController
@RequestMapping("/goods")
public class GoodsController {
@Autowired
private GoodsService goodsService;
@GetMapping("/findOne/{id}")
public Goods findOne(@PathVariable("id") int id) {
return goodsService.findOne(id);
}
}
GoodsService:
package com.itheima.provider.service;
import com.itheima.provider.dao.GoodsDao;
import com.itheima.provider.domain.Goods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Goods service layer
*/
@Service
public class GoodsService {
@Autowired
private GoodsDao goodsDao;
/**
* Query by id
*/
public Goods findOne(int id) {
return goodsDao.findOne(id);
}
}
Goods entity:
package com.itheima.provider.domain;
/**
* Goods entity class
*/
public class Goods {
private int id;
private String title;
private double price;
private int count;
public Goods() {}
public Goods(int id, String title, double price, int count) {
this.id = id;
this.title = title;
this.price = price;
this.count = count;
}
// getters and setters
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }
public int getCount() { return count; }
public void setCount(int count) { this.count = count; }
}
GoodsDao:
package com.itheima.provider.dao;
import com.itheima.provider.domain.Goods;
import org.springframework.stereotype.Repository;
@Repository
public class GoodsDao {
public Goods findOne(int id) {
return new Goods(1, "Huawei Phone", 3999, 10000);
}
}
ProviderApp:
package com.itheima.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class, args);
}
}
application.yml:
server:
port: 8000
3.2.1.3 Create Service Consumer
- Create service consumer
eureka-consumer
![1587522756792]
- Final directory structure
![1587522649367]
OrderController:
package com.itheima.consumer.controller;
import com.itheima.consumer.domain.Goods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Service caller
*/
@RestController
@RequestMapping("/order")
public class OrderController {
@GetMapping("/goods/{id}")
public Goods findGoodsById(@PathVariable("id") int id) {
System.out.println("findGoodsById..." + id);
// Remote call to Goods service's findOne interface
return null;
}
}
Goods entity (same as provider):
package com.itheima.consumer.domain;
public class Goods {
private int id;
private String title;
private double price;
private int count;
// constructors, getters, setters omitted for brevity
}
ConsumerApp:
package com.itheima.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
}
}
application.yml:
server:
port: 9000
3.2.2 Remote Call with RestTemplate
- Spring provides a simple and convenient template class
RestTemplatefor accessing RESTful services in Java code. - It is similar to
HttpClientbut more elegant and easier to use.
Modify the consumer code:
RestTemplateConfig:
package com.itheima.consumer.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
OrderController:
package com.itheima.consumer.controller;
import com.itheima.consumer.domain.Goods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/goods/{id}")
public Goods findGoodsById(@PathVariable("id") int id) {
System.out.println("findGoodsById..." + id);
String url = "http://localhost:8000/goods/findOne/" + id;
Goods goods = restTemplate.getForObject(url, Goods.class);
return goods;
}
}
3.2.3 Eureka Server Setup
- Create
eureka-servermodule. - Add SpringCloud and eureka-server dependencies.
pom.xml for spring-cloud-parent (add Spring Cloud dependency management):
<properties>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
pom.xml for eureka-server:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
EurekaApp:
package com.itheima.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaApp {
public static void main(String[] args) {
SpringApplication.run(EurekaApp.class, args);
}
}
- Configure Eureka Server.
application.yml:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
register-with-eureka: false
fetch-registry: false
- Start the module.
3.2.4 Eureka Console Introduction
![1587524898190]
![1587524966009]
- System status: System status information
- DS Replicas: Cluster information
- Instances currently registered with Eureka: Instance registration information
- General Info: General information
- Instance Info: Instance information
3.2.5 Eureka Client
- Add eureka-client dependencies.
pom.xml for eureka-provider:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
ProviderApp:
package com.itheima.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient
@SpringBootApplication
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class, args);
}
}
- Configure eureka client.
application.yml for eureka-provider:
server:
port: 8001
eureka:
instance:
hostname: localhost
client:
service-url:
defaultZone: http://localhost:8761/eureka
spring:
application:
name: eureka-provider
- Start and test.
![1587525778719]
Similarly, configure eureka-consumer to appear in the console.
ConsumerApp:
package com.itheima.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
}
}
application.yml:
server:
port: 9000
eureka:
instance:
hostname: localhost
client:
service-url:
defaultZone: http://localhost:8761/eureka
spring:
application:
name: eureka-consumer
![1587526247520]
3.2.6 Dynamic URL Retrieval
Modify ConsumerApp to use @EnableDiscoveryClient:
package com.itheima.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
}
}
Modify OrderController to dynamically retrieve the provider URL:
package com.itheima.consumer.controller;
import com.itheima.consumer.domain.Goods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/goods/{id}")
public Goods findGoodsById(@PathVariable("id") int id) {
List<ServiceInstance> instances = discoveryClient.getInstances("EUREKA-PROVIDER");
if (instances == null || instances.isEmpty()) {
return null;
}
ServiceInstance instance = instances.get(0);
String host = instance.getHost();
int port = instance.getPort();
String url = "http://" + host + ":" + port + "/goods/findOne/" + id;
return restTemplate.getForObject(url, Goods.class);
}
}
3.3 Eureka Configuration Properties
3.3.1 Instance-related Properties
![1587526675591]
Eureka Instance configuraton is stored in org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean. It implements com.netflix.appinfo.EurekaInstanceConfig.
Configuration uses eureka.instance.xxx format.
Key properties:
appname: Application name. First takesspring.application.name, default "unknown".appGroupName: Application group name.instanceEnabledOnit: Whether to enable communication immediately upon registration. Default false.nonSecurePort: Non-secure port. Default 80.securePort: Secure port. Default 443.nonSecurePortEnabled: Enable non-secure port. Default true.securePortEnabled: Enable secure port. Default false.leaseRenewalIntervalInSeconds: Lease renewal interval. Default 30.leaseExpirationDurationInSeconds: Lease expiration duration. Default 90.virtualHostName: Virtual host name. Defaultspring.application.nameor "unknown".instanceId: Unique instance ID.metadataMap: Instance metadata.dataCenterInfo: Data center information. DefaultMyOwn.ipAddress: IP address.statusPageUrlPath: Status page relative URL. Default/actuator/info.statusPageUrl: Status page absolute URL.homePageUrlPath: Home page relative URL. Default/.homePageUrl: Home page absolute URL.healthCheckUrlPath: Health check relative URL. Default/actuator/health.healthCheckUrl: Health check absolute URL.namespace: Configuration namespace (ignored in Spring Cloud). Default "eureka".hostname: Hostname. If not set, uses OS hostname.preferIpAddress: Prefer IP address over hostname. Default false.
3.3.2 Server-related Properties
![1587526704046]
Eureka Server configuration is stored in org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean, implementing com.netflix.eureka.EurekaServerConfig.
Configuration uses eureka.server.xxx format.
Key properties:
enableSelfPreservation: Enable self-preservation. Default true.renewalPercentThreshold: Self-preservation renewal percentage threshold. Default 0.85.renewalThresholdUpdateIntervalMs: Renewal threshold update interval. Default 15 minutes.peerEurekaNodesUpdateIntervalMs: Peer node update interval. Default 10 minutes.enableReplicatedRequestCompression: Enable replication request compression. Default false.waitTimeInMsWhenSyncEmpty: Wait time when sync is empty. Default 5 minutes.peerNodeConnectTimeoutMs: Peer node connect timeout. Default 200.peerNodeReadTimeoutMs: Peer node read timeout. Default 200.peerNodeTotalConnections: Total peer node connections. Default 1000.peerNodeTotalConnectionsPerHost: Connections per host. Default 500.peerNodeConnectionIdleTimeoutSeconds: Connection idle timeout. Default 30.retentionTimeInMSInDeltaQueue: Delta queue retention time. Default 3 minutes.deltaRetentionTimerIntervalInMs: Delta cleanup interval. Default 30 seconds.evictionIntervalTimerInMs: Eviction task interval. Default 60 seconds.responseCacheAutoExpirationInSeconds: Response cache auto expiration. Default 180.responseCacheUpdateIntervalMs: Response cache update interval. Default 30 seconds.useReadOnlyResponseCache: Use read-only response cache. Default true.disableDelta: Disable delta for clients. Default false.maxThreadsForStatusReplication: Max threads for status replication. Default 1.maxElementsInStatusReplicationPool: Max elements in status replication pool. Default 10000.syncWhenTimestampDiffers: Sync when timestamps differ. Default true.registrySyncRetries: Registry sync retries. Default 0.registrySyncRetryWaitMs: Registry sync retry wait. Default 30 seconds.maxElementsInPeerReplicationPool: Max elements in peer replication pool. Default 10000.minThreadsForPeerReplication: Min threads for peer replication. Default 5.maxThreadsForPeerReplication: Max threads for peer replication. Default 20.maxTimeForReplication: Max replication time. Default 30000 ms.disableDeltaForRemoteRegions: Disable remote region delta. Default false.remoteRegionConnectTimeoutMs: Remote region connect timeout. Default 1000.remoteRegionReadTimeoutMs: Remote region read timeout. Default 1000.remoteRegionTotalConnections: Max remote region connections. Default 1000.remoteRegionTotalConnectionsPerHost: Connections per host. Default 500.remoteRegionConnectionIdleTimeoutSeconds: Remote region connection idle timeout. Default 30.remoteRegionRegistryFetchInterval: Remote region fetch interval. Default 30 seconds.remoteRegionFetchThreadPoolSize: Remote region fetch thread pool size. Default 20.
3.4 Eureka High Availability
![1587526769913]
- Prepare two Eureka Servers.
- Configure them to register with each other.
- Configure Eureka Clients to register with both servers.
3.4.1 Setup
Create eureka-server-1:
pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
application.yml:
server:
port: 8761
eureka:
instance:
hostname: eureka-server1
client:
service-url:
defaultZone: http://eureka-server2:8762/eureka
register-with-eureka: true
fetch-registry: true
spring:
application:
name: eureka-server-ha
Eureka1App:
package eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class Eureka1App {
public static void main(String[] args) {
SpringApplication.run(Eureka1App.class, args);
}
}
Create eureka-server-2:
Similar structure, with application.yml:
server:
port: 8762
eureka:
instance:
hostname: eureka-server2
client:
service-url:
defaultZone: http://eureka-server1:8761/eureka
register-with-eureka: true
fetch-registry: true
spring:
application:
name: eureka-server-ha
Eureka2App:
package eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class Eureka2App {
public static void main(String[] args) {
SpringApplication.run(Eureka2App.class, args);
}
}
Modify local host file to map eureka-server1 and eureka-server2 to localhost.
![1587527369390]
![1587527469782]
3.4.2 Client Testing
Modify service provider and consumer configuration files to point to both Eureka servers.
application.yml for eureka-provider:
server:
port: 8001
eureka:
instance:
hostname: localhost
prefer-ip-address: true
ip-address: 127.0.0.1
instance-id: ${eureka.instance.ip-address}:${spring.application.name}:${server.port}
lease-renewal-interval-in-seconds: 3
lease-expiration-duration-in-seconds: 9
client:
service-url:
defaultZone: http://eureka-server1:8761/eureka,http://eureka-server2:8762/eureka
spring:
application:
name: eureka-provider
application.yml for eureka-consumer:
server:
port: 9000
eureka:
instance:
hostname: localhost
client:
service-url:
defaultZone: http://eureka-server1:8761/eureka,http://eureka-server2:8762/eureka
spring:
application:
name: eureka-consumer
Test results:
![1587527850803]
![1587527811851]
3.5 Consul
3.5.1 Consul Overview
- Consul is developed by HashiCorp using Go language. It supports multiple data centers, distributed high availability for service publication and registration.
- Used for service discovery and configuration in distributed systems.
- Easy to use, naturally portable (supports Linux, Windows, Mac OS X). The installation package contains only a single executable file, making deployment easy.
- Official website: https://www.consul.io
Start Consul in dev mode:
![1587528140341]
Dev mode: no data persistence.
Successful startup:
![1587528221446]
Console:
![1587528280115]
3.5.2 Consul Quick Start
![1587527962928]
- Build Provider and Consumer services.
- Use RestTemplate for remote calls.
- Register Provider service with Consul.
- Consumer service fetches Provider address from Consul to complete remote calls.
pom.xml for Provider:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
application.yml:
server:
port: 8000
spring:
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
prefer-ip-address: true
application:
name: consul-provider
pom.xml for Consumer:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
application.yml:
server:
port: 9000
spring:
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
prefer-ip-address: true
application:
name: consul-consumer
OrderController:
package com.itheima.consul.controller;
import com.itheima.consul.domain.Goods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/goods/{id}")
public Goods findGoodsById(@PathVariable("id") int id) {
List<ServiceInstance> instances = discoveryClient.getInstances("consul-PROVIDER");
if (instances == null || instances.isEmpty()) {
return null;
}
ServiceInstance instance = instances.get(0);
String host = instance.getHost();
int port = instance.getPort();
String url = "http://" + host + ":" + port + "/goods/findOne/" + id;
return restTemplate.getForObject(url, Goods.class);
}
}
![1587538853089]
3.6 Nacos
3.6.1 Nacos Overview
- Nacos (Dynamic Naming and Configuration Service) is an open-source project from Alibaba released in July 2018.
- It focuses on service discovery and configuration management, helping you discover, configure, and manage microservices. Nacos supports almost all major types of "services".
- In short, Nacos = Spring Cloud Registry + Spring Cloud Configuration Center.
- Official website: https://nacos.io/
- Download: https://github.com/alibaba/nacos/releases
Start Nacos:
![1587539022443]
Successful startup:
![1587539056744]
Console login:
Username and password: nacos
![1587539128223]
Console page:
![1587539185231]
Spring Cloud Alibaba components:
![1587539317677]
3.6.2 Nacos Quick Start
pom.xml for Provider:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
application.yml:
server:
port: 8000
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: nacos-provider
pom.xml for Consumer:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
application.yml:
server:
port: 9000
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: nacos-consumer
Console display:
![1587540058184]
Detail page:
![1587539884192]
Example code:
![1587539969096]