到现在也没有实践过微服务的我…..
这个例子的github地址,https://github.com/dongjx/vagrant-consul-cluster
微服务架构
将一个完整的应用(单体应用)按照一定的拆分规则拆分成多个不同的服务,每个服务都能独立地进行开发、部署、扩展。服务于服务之间通过注入RESTful api或其他方式调用
项目规划
项目名称 | 端口 | 描述 | URL |
---|---|---|---|
ConsulCluster | 8500 | 注册中心 | |
UserService | 8600 | 服务提供者 | /users |
AgentService | 8601 | 服务提供者 | /agents |
ConsumerService | 8602 | 服务消费者 | / |
consul的安装与启动
- 安装
brew install consul
- 启动
./consul agent -dev # -dev表示开发模式运行,另外还有-server表示服务模式运行
- 访问
http://127.0.0.1:8500/ui/
consul常用命令
命令 | 解释 | 示例 |
---|---|---|
agent | 运行一个consul agent | consul agent -dev |
join | 将agent加入到consul集群 | consul join IP |
members | 列出consul cluster集群中的members | consul members |
leave | 将节点移除所在集群 | consul leave |
consul的高可用
使用vagrant来创建consul集群
主机名称 | IP | 作用 | 是否允许远程访问 |
---|---|---|---|
consul1 | 172.20.20.10 | consul server | 是 |
consul2 | 172.20.20.11 | consul client | 否 |
consul3 | 172.20.20.12 | consul client | 是 |
安装与配置vagrant
- 安装
brew cask install virtualbox
如果有安装不成功,可能是需要到System Preferences → Security & Privacy → General点一下右下角的allow mkdir consulcluster
cd consulcluster
vagrant init centos/7
vim Vagrantfile
并修改:
# -*- mode: ruby -*-
# vi: set ft=ruby :
$script = <<SCRIPT
echo "Installing dependencies ..."
yum install -y epel-release
yum install -y jq
yum install -y unzip
echo "Determining Consul version to install ..."
CHECKPOINT_URL="https://checkpoint-api.hashicorp.com/v1/check"
if [ -z "$CONSUL_DEMO_VERSION" ]; then
CONSUL_DEMO_VERSION=$(curl -s "${CHECKPOINT_URL}"/consul | jq .current_version | tr -d '"')
fi
echo "Fetching Consul version ${CONSUL_DEMO_VERSION} ..."
cd /tmp/
curl -s https://releases.hashicorp.com/consul/${CONSUL_DEMO_VERSION}/consul_${CONSUL_DEMO_VERSION}_linux_amd64.zip -o consul.zip
echo "Installing Consul version ${CONSUL_DEMO_VERSION} ..."
unzip consul.zip
sudo chmod +x consul
sudo mv consul /usr/bin/consul
SCRIPT
# Specify a custom Vagrant box for the demo
DEMO_BOX_NAME = "centos/7"
# Vagrantfile API/syntax version.
# NB: Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = DEMO_BOX_NAME
config.vm.provision "shell", inline: $script
config.vm.define "consul1" do |consul1|
consul1.vm.hostname = "consul1"
consul1.vm.network "private_network", ip: "172.20.20.10"
end
config.vm.define "consul2" do |consul2|
consul2.vm.hostname = "consul2"
consul2.vm.network "private_network", ip: "172.20.20.11"
end
config.vm.define "consul3" do |consul3|
consul3.vm.hostname = "consul3"
consul3.vm.network "private_network", ip: "172.20.20.12"
end
end
vagrant up
, 三个虚拟机启动
启动虚拟机上的consul服务
- 启动consul1的服务:
vagrant ssh consul1
su - //默认password: vagrant
nohup consul agent -data-dir /tmp/consul1 -node=consul1 -bind=172.20.20.10 -datacenter=dc1 -ui -client=172.20.20.10 -server -bootstrap-expect 1 &
- 启动consul2的服务:
vagrant ssh consul2
su - //默认password: vagrant
nohup consul agent -data-dir /tmp/consul2 -node=consul2 -bind=172.20.20.11 -datacenter=dc1 -ui &
- 启动consul3的服务:
vagrant ssh consul3
su - //默认password: vagrant
nohup consul agent -data-dir /tmp/consul3 -node=consul3 -bind=172.20.20.12 -datacenter=dc1 -ui -client=0.0.0.0 &
- 将consul2, consul3加到consul1
vagrant ssh consul2
su - //默认password: vagrant
consul join 172.20.20.10
vagrant ssh consul3
su - //默认password: vagrant
consul join 172.20.20.10
- 查看集群状态:
> consul members
Node Address Status Type Build Protocol DC Segment
consul1 172.20.20.10:8301 alive server 1.2.3 2 dc1 <all>
consul2 172.20.20.11:8301 alive client 1.2.3 2 dc1 <default>
consul3 172.20.20.12:8301 alive client 1.2.3 2 dc1 <default>
- 访问
172.20.20.10:8500
服务提供方
UserService(spring-boot + mvn)
- 在pom.xml中加入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
spring-boot-starter-actuator 是health check的依赖
- 修改
xxxApplication.java
@EnableDiscoveryClient
@SpringBootApplication
public class MicroserviceProducerUserApplication {
public static void main(String[] args) {
SpringApplication.run(MicroserviceProducerUserApplication.class, args);
}
}
- 修改
application.properties
server.port=8600
spring.application.name=UserService
spring.cloud.consul.host=172.20.20.10
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.register=true
-
加入users api,
/users
详情请看代码,https://github.com/dongjx/vagrant-consul-cluster/tree/master/microservice-producer-user -
访问consul的控制台 http://127.20.20.10:8500 ,可以看到注册上的服务信息, 或访问 http://172.20.20.10:8500/v1/agent/services
Agent Service
类似UserService, 提供api /agents
服务消费者
- 类似UserService, 创建ConsumerService(消费者可以注册到Consul也可以不注册spring.cloud.consul.discovery.register=false)
- 在ConsumerService中,调用其他服务
@RestController
public class HomeController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
/**
* 获取所有服务
*/
@GetMapping("/services")
public Object services() {
return discoveryClient.getInstances("UserService");
}
@GetMapping
public List index() {
ServiceInstance serviceInstance = loadBalancerClient.choose("UserService");
System.out.println("服务地址:" + serviceInstance.getUri());
System.out.println("服务名称:" + serviceInstance.getServiceId());
List callServiceResult = restTemplate.getForObject(serviceInstance.getUri().toString() + "/users", List.class);
System.out.println(callServiceResult);
return callServiceResult;
}
}
- 启动两个UserService的实例
java -Dserver.port=8503 -jar target/microservice-producer-user-0.0.1-SNAPSHOT.jar
java -Dserver.port=8600 -jar target/microservice-producer-user-0.0.1-SNAPSHOT.jar
-
启动AgentService
-
启动ConsumerService
访问http://localhost:8602/services
查看所有services
访问http://localhost:8602/
ServerList:ConsulServerList{serviceId='UserService', tag=null}
服务地址:http://10.206.20.242:8503
服务名称:UserService
[annie, zoe]
2018-10-09 17:44:05.976 INFO 47637 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty : Flipping property: UserService.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
服务地址:http://10.206.20.242:8600
服务名称:UserService
[annie, zoe]
发现强大的Consul已经实现了负载均衡