Speaking in front of the Eureka and Spring Cloud Config, today introduced a versatile player, "Consul." It is HashiCorp introduced, providing tools for service discovery and service configuration. Go with language development, has good portability. The Spring Cloud incorporate, Eureka stop the development of the new version, more developers want to use Consul registered as a service discovery to use.
Consul functions provided include the following:
Service Discovery
Consul allow service registration and service discovery (via DNS and HTTP interface) easier, even for external services (eg SaaS) registered the same.
Troubleshooting
Health checks, the service discovery request can be routed to prevent unhealthy host, and can make the service easily broken (no longer available).
Multi-data center
Consul does not require complex configuration can be extended to multiple simple data centers to find other service data center or request service only current data centers.
Key-value store
Flexible key-value store, providing dynamic configuration, signature, collaboration, leader election and other functions, to achieve long polling configuration changes through immediate notification.
Spring Cloud Consul Consul will be automatically configured and further encapsulated.
Spring Cloud Consul can replace existing Spring Cloud Eureka, which is registered as service discovery framework. And Eureka 2.x versions has stopped development, and the government has also proposed to use Spring Cloud Spring Cloud Consul in place, of course, if you have used in the Eureka project does not matter, Eureka is stable enough, normal use without any problems.
Spring Cloud Consul can replace existing Spring Cloud Config, which is use as a distribution center.
Spring Cloud Consul found mainly used for service registration and the official suggested alternative Eureka, then it must have a Eureka or other frameworks do not have the advantage, look at the following comparison and contrast it to other services to find a way to do (taken from the network):
function points | euerka | Consul | zookeeper | etcd |
---|---|---|---|---|
Health Check Service | It can be equipped with support | Service status, memory, hard drive, etc. | (Weak) long connection, keepalive | Heartbeat connection |
Multi-data center | — | stand by | — | — |
kv storage services | — | stand by | stand by | stand by |
consistency | — | raft | paxos | raft |
cap | ap (high availability, fault-tolerant partition) | CA (coincidence data, availability) | cp | cp |
Using an interface (multi-language) | http(sidecar) | Supports http and dns | Client | http/grpc |
watch support | Support long polling / Much of the increase | Full amount / support long polling | stand by | Support long polling |
Self-monitoring | metrics | metrics | — | metrics |
Safety | — | acl /https | acl | https support (weak) |
spring cloud integration | It has supported | It has supported | It has supported | It has supported |
Consul raft using algorithms to ensure data consistency and strong, so the benefits are obvious, the corresponding also brought some sacrifice:
- Registration service will be slower compared to Eureka. Consul of the raft because protocol requires a majority of nodes must have successfully written only considered successful registration;
- When Leader hang up, during the re-election of the entire consul is not available, in order to ensure strong consistency at the expense of usability.
Consul installation and startup
Eureka and different, Consul requires a separate install, can go to the official website (https://www.consul.io/downloads.html) download. Depending on the specific installation of the operating system, refer to the official website.
Consul provides a range of parameters for the command line. Consul provides a default web UI interface to view the configuration. You can be accessed through the web UI console port access server in 8500.
The development process, we can command consul agent -dev
to start the development mode, after a successful start, visit localhost: 8500 you can see all the services of the current consul. As shown below:
In the production of more deployment of search-related self-introduction, here it is only started with the dev mode, used to introduce the use of Spring Cloud Consul.
Achieve service provider
1, reference spring-cloud-consul
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-all</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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-consul-dependencies</artifactId>
<version>2.1.0.M2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2, consul configuration settings in the configuration file bootstrap.yml, the configuration is as follows:
spring:
cloud:
consul:
discovery:
service-name: consul-provider ## 服务提供者名称
host: localhost ## consul 所在服务地址
port: 8500 ## consul 端口
3, server configuration settings in the configuration file application.yml, the configuration is as follows:
spring:
application:
name: consul-provider
server:
port: 5000
endpoints:
health:
sensitive: false
restart:
enabled: true
shutdown:
enabled: true
management:
security:
enabled: false
4, add a RestController, write two methods testing services
@RestController
@Slf4j
public class HelloController {
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping(value = "test")
public String test(){
List<String> services = discoveryClient.getServices();
for(String s : services){
log.info(s);
}
return "hello spring cloud!";
}
@GetMapping(value = "nice")
public String nice(){
List<String> services = discoveryClient.getServices();
for(String s : services){
log.info("gogogo" + s);
}
return "nice to meet you!";
}
}
5, Spring boot startup class
@SpringBootApplication
@EnableDiscoveryClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@EnableDiscoveryClient notes indicate this is a client-side.
Start the service provider, open http: // localhost: 8500 you can see this service
Achieve service consumers
1, reference related maven package, in addition to the above-referenced service provider the same package, but also references openFeign
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2, bootstrap.yml configuration because as a service to consumers, so the setting is not registered with the consul
spring:
cloud:
consul:
discovery:
register: false
3, application.yml configuration
spring:
application:
name: consul-customer
server:
port: 5001
endpoints:
health:
sensitive: false
restart:
enabled: true
shutdown:
enabled: true
management:
security:
enabled: false
4, project startup class
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Application {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Use @EnableDiscoveryClient notes indicate as a service client-side, @ EnableFeignClients enabled openFeign.
5, create a service interface openFeign
@FeignClient(value = "consul-provider")
public interface IHelloService {
@RequestMapping(value = "/hello")
String hello();
@RequestMapping(value = "nice")
String nice();
}
RESTful interface address corresponding to two service provider provided
6, to achieve a RestController open access service providers out of service
@RestController
public class ConsumerController {
@Autowired
private LoadBalancerClient loadBalancer;
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
@Autowired
private IHelloService helloService;
private final static String SERVICE_NAME = "consul-provider";
/**
* 使用普通的 RestTemplate 方法访问服务
*
* @return
*/
@GetMapping(value = "test")
public Object test() {
String result = restTemplate.getForObject("http://"+SERVICE_NAME + "/test", String.class);
System.out.println(result);
return result;
}
/**
* 使用 openFeign 方式访问服务
*
* @return
*/
@GetMapping(value = "feign")
public Object feign() {
String s = helloService.nice();
return s;
}
/**
* 获取所有服务实例
*
* @return
*/
@GetMapping(value = "/services")
public Object services() {
return discoveryClient.getInstances(SERVICE_NAME);
}
/**
* 从所有服务中选择一个服务(轮询)
*/
@GetMapping(value = "/choose")
public Object choose() {
return loadBalancer.choose(SERVICE_NAME).getUri().toString();
}
}
Consumers start the program, and then visit the corresponding RESTful interface, you can get the corresponding results.
High availability service provider
Micro service line is best not to form a single point, to start the next two service providers through configuration, as long as the same service-name, it means that this is the same service.
1, bootstrap.yml configuration unchanged
spring:
cloud:
consul:
discovery:
service-name: consul-provider
host: localhost
port: 8500
2, application.yml modified as follows
spring:
profiles:
active: consul-provider1
endpoints:
health:
sensitive: false
restart:
enabled: true
shutdown:
enabled: true
management:
security:
enabled: false
---
spring:
profiles: consul-provider1
application:
name: consul-provider1
server:
port: 5000
---
spring:
profiles: consul-provider2
application:
name: consul-provider2
server:
port: 5002
3, after the start time plus vm parameters. Plus parameters were:
-Dspring.profiles.active=consul-provider1
-Dspring.profiles.active=consul-provider2
Respectively provider consul-provider in the port 5000 and 5002 to start the service port
4, the last still access the consumer's address RESTful interface, you can see examples of service calls per request of the service provider background.
Used as a distribution center
We know, Spring Cloud Config Center provides the ability to configure, but need to meet git, svn or external storage (eg various databases), since then the use of the Consul, you can use the configuration center functions Consul offered, and no additional git, svn, database used in conjunction.
Next, briefly explain how Spring Cloud Consul used as a distribution center. Consul yaml support profiles and content format properties, in the present embodiment, an example yaml format.
1, reference related maven package
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</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>
2, bootstrap.yml configuration, where the main set of parameters about config
spring:
cloud:
consul:
config:
enabled: true # 启用配置中心
format: yaml # 指定配置格式为 yaml
data-key: mysql_config # 也就是 consul 中 key/value 中的 key
prefix: config # 可以理解为配置文件所在的最外层目录
defaultContext: consul-config # 可以理解为 mysql_config 的上级目录
discovery:
register: false
Corresponds to the consul, key / value in the configuration is as follows:
3, application.yml profile contents
spring:
application:
name: consul-config
server:
port: 5008
endpoints:
health:
sensitive: false
restart:
enabled: true
shutdown:
enabled: true
management:
security:
enabled: false
4, the profile is defined entity class, designated @ConfigurationProperties annotation specified prefix mysql, i.e. key / value profile top key.
@Component
@ConfigurationProperties(prefix = "mysql")
public class MySqlComplexConfig {
public static class UserInfo{
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "UserInfo{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
private String host;
private UserInfo user;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public UserInfo getUser() {
return user;
}
public void setUser(UserInfo user) {
this.user = user;
}
}
5, a new RestController to obtain the output value content
@RestController
@Slf4j
public class ConfigController {
@Autowired
private MySqlConfig mySqlConfig;
@Autowired
private MySqlComplexConfig mySqlComplexConfig;
@GetMapping(value = "mysqlhost")
public String getMysqlHost(){
return mySqlConfig.getHost();
}
@GetMapping(value = "mysqluser")
public String getMysqlUser(){
log.info(mySqlComplexConfig.getHost());
MySqlComplexConfig.UserInfo userInfo = mySqlComplexConfig.getUser();
return userInfo.toString();
}
}
6, finally, launch applications, access RestController the RESTful interface to see the contents of the configuration file.
Compared with the Spring Cloud Config, Consul after modifying the configuration console, it will be updated immediately, no need to combine with Spring Cloud Bus of the class.
Source address
If you feel that writing can, please point a " recommendation " bar
Welcome attention occasionally update this series and other articles
古时的风筝
, enter the number of the public can join the exchange group