consul 服务注册中心
简介:consul 基于go 语言开发的服务注册中心 轻量级服务注册中心 google开发
作用: 管理微服务中所有的服务 注册 发现 管理 服务元数据信息存储(服务名 地址列表) 心跳健康检测

consul 服务中心安装
下载地consul

https://www.consul.io/downloads

在指定目录解压,注意:不建议目录包含中文

E:\consul\consul.exe

启动服务注册中心 在consul 安装目录打开cmd

consul agent -dev 

访问consul 管理界面

浏览器输入:http://localhost:8500

管理界面基本介绍

 dc1:数据中心名称:datacenter 默认为:dc1
 指定数据中心启动 consul agent -dev -datacenter=sss
 services :当前consul 服务中注册服务列表 ,默认:client server 同时启动自己注册自己 会出现一个consul 一个服务
 nodes 查看集群的节点
 key/value  存储 数据
 ACL 版本集成控制
 Intentions 集成其他第三方组件

推荐 配置环境变量

path:Econsul(自己安装consul目录)

登录命令,然后输入密码

mysql -uroot -p

创建数据

CREATE  DATRABSE [数据库名字]

选择数据库

use [数据库名]

导入sql文件,登录了后在use 选了数据库在可以执行

   source [所在的路径//*.sql] 

Single Threaded Execution 有时也会被称之为 临界区。表示 临界区 内的代码同一时间内只允许一个线程执行,这个模式是并发编程的基础,对应 Java 中也就是同步代码块 synchronized,或其他显式锁 lock

多线程环境
多个线程同时访问的共享资源
这些线程会改变共享资源。

示例
现有票 100 张,分三个窗口售卖,卖完为止。

票类:

public class Ticket {

    private int counter = 100;

    public void sell() {
        if (counter > 0) {
            System.out.println(Thread.currentThread().getName() + "号窗口卖出:" + this.counter-- + "号票");
        } else {
            System.out.println("票已卖完");
        }
    }

}

窗口类:

public class StationThread extends Thread {

    private final Ticket ticket;

    public StationThread(String name, Ticket ticket) {
        super(name);
        this.ticket = ticket;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ticket.sell();
        }
    }
}

测试类:

public class Main {

    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new StationThread("S1", ticket).start();
        new StationThread("S2", ticket).start();
        new StationThread("S3", ticket).start();
    }
}

请输入图片描述

很明显的可以看到,同一张票,被多个窗口同时售卖了,就是因为未对共享资源 Ticket 做保护,导致了这种情况。

解决办法也很简单,给 Ticket 的 sell 方法加上 synchronized 即可。这样就防止了多个窗口同时访问同一张票。

public class Ticket {

    private int counter = 100;

    public synchronized void sell() {
        if (counter > 0) {
            System.out.println(Thread.currentThread().getName() + "号窗口卖出:" + this.counter-- + "号票");
        } else {
            System.out.println("票已卖完");
        }
    }

}

类图

请输入图片描述

时序图

请输入图片描述

总结
单线程的情况,不需要使用此模式,就好像一个人在家上厕所,不需要锁门一样。

只有当 多线程 同时对 同一个共享资源,在线程中 进行了修改,才需要使用此模式。

且需要注意,对于 共享资源,如果用到了此模式,要保证所有使用他的地方都进行了保护。不然等于你把门锁住了,但窗子没关。

集群实例

集群搭建

完全集群

创建3个springboot项目
引入eureka server 依赖
配置文件application.properties
tips:node为一个微小的springboot项目

node1: server.port=8761

      http://localhost:8762/eureka,http://localhost:8763/eureka

node2: server.port=8762

      http://localhost:8761/eureka,http://localhost:8763/eureka

node3: server.port=8763

      http://localhost:8761/eureka,http://localhost:8762/eureka

在每个项目main方法加入

@EnableEurekaServer 注解

引入依赖

<!-- 引入Eureka Client-->

<dependency>

    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

写配置

#指定服务端口
server.port=8989
#指定 服务名称
spring.application.name=EUREKACLIENT
#eureka server 服务注册中心地址 暴露服务地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka

#用来修改eureka server 默认接受心跳最大时间 默认是90s
eureka.instance.lease-expiration-duration-in-seconds=10
#指定客户端多久向eureka server 发送一次心跳 默认是30s
eureka.instance.lease-renewal-interval-in-seconds=5

加注解

Application main方法上面加上这个注解
@EnableEurekaClient //让当前微服务作为一个eurekaserver客户端进行服务注册