1、CentOS 7镜像下载

阿里云站点:http://mirrors.aliyun.com/centos/7/isos/x86_64/
各个版本的ISO镜像文件说明:
站点截图

  • CentOS-7-x86_64-DVD-1708.iso 标准安装版(推荐)
  • CentOS-7-x86_64-Everything-1708.iso 完整版,集成所有软件
  • CentOS-7-x86_64-Minimal-1708.iso 精简版,自带的软件最少

2、centos7安装教程

使用VMware安装centos教程

3、xshell连接centos

查看IP:参考链接
发现 ens33 没有 inet 这个属性的
终端截图

1
vi /etc/sysconfig/network-scripts/ifcfg-ens33


把这一项改为YES(ONBOOT=yes)

使用xshell连接:

4 、JDK安装教程

参考文章

一、检查是否已安装JDK及卸载
1
2
3
# (以下命令二选一)
yum list installed | grep [java][jdk]
rpm -qa | grep [java][jdk][gcj]


执行命令出现如上图所示,需要卸载,反之即不用

  • 卸载JAVA环境
    1
    2
    yum -y remove java-1.8.0-openjdk*  //表时卸载所有openjdk相关文件输入
    yum -y remove tzdata-java.noarch //卸载tzdata-java
二、安装JDK
  • 查看JDK软件包列表

    1
    yum search java | grep -i --color jdk
  • 选择版本安装

1
yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
  • 或者如下命令,安装jdk1.8.0的所有文件
1
yum install -y java-1.8.0-openjdk*
  • 查看JDK是否安装成功
1
java -version
三、配置环境变量
  • JDK默认安装路径/usr/lib/jvm
  • 使用vi /etc/profile命令添加如下配置
    1
    2
    3
    4
    5
    # set java environment  
    JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64
    PATH=$PATH:$JAVA_HOME/bin
    CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    export JAVA_HOME CLASSPATH PATH

保存关闭profile文件,执行如下命令生效

1
source  /etc/profile

使用如下命令,查看JDK变量

1
2
3
echo $JAVA_HOME
echo $PATH
echo $CLASSPATH

5、SpringBoot 项目在linux后台守护进程运行

参考链接

1
nohup java -jar /usr/actuator-0.0.1-SNAPSHOT.jar --server.port=8080  >logName.log 2>&1 &

命令详解:

  • nohup:不挂断地运行命令,退出帐户之后继续运行相应的进程。

  • logName.log :是nohup把command的输出重定向到当前目录的指定的“日志文件名.log”文件中,即输出内容不打印到屏幕上,而是输出到”日志文件名.log”文件中。不指定文件名会在当前目录创建nohup.out,如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。

  • 2>&1:2就是标准错误,1是标准输出,该命令相当于把标准错误重定向到标准输出么。这里&相当于标准错误等效于标准输出,即把标准错误和标准输出同时输出到指定的“日志文件名.log”文件中。

  • java -jar springbootProjectName.jar:执行springboot的项目,如果单单只执行该命令,linux只会短暂的运行该项目,当退出控制台后会自动关闭该项目。

  • 最后的&:让该项目在后台运行。

注意: bash: nohup: command not found解决方法:
参考链接

  • 查看本地是否有
    1
    which nohup

  • 到当前用户的根目录(我的是root)
1
2
cd ~
vi .bash_profile

在原来后边加上:/usr/bin,保存,退出

  • 使文件立刻生效
1
source ~/.bash_profile
  • 查看是否成功
    1
    nohup --version


如果第一步就没有发现nohup,先安装,再配置

1
yum install coreutils

6、外部访问项目

1
2
# 虚拟机内部链接测试(确保项目运行正常):
curl http://localhost:8080/hello

外部访问必须关闭防火墙或者开放相应的端口

  • 关闭防火墙

  • 开放端口(开放端口需要重启防火墙)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    开启端口
    [root@centos7 ~]# firewall-cmd --zone=public --add-port=80/tcp --permanent

    查询端口号80 是否开启:
    [root@centos7 ~]# firewall-cmd --query-port=80/tcp

    重启防火墙:
    [root@centos7 ~]# firewall-cmd --reload

    查询有哪些端口是开启的:
    [root@centos7 ~]# firewall-cmd --list-port

    命令含义:
    --zone #作用域
    --add-port=80/tcp #添加端口80,格式为:端口/通讯协议
    --permanent #永久生效,没有此参数重启后失效
1
2
3
4
5
6
7
8
9
10
11
12
1.启动防火墙
systemctl start firewalld
2.禁用防火墙
systemctl stop firewalld
3.设置开机启动
systemctl enable firewalld
4.停止并禁用开机启动
sytemctl disable firewalld
5.重启防火墙
firewall-cmd --reload
6.查看状态
systemctl status firewalld或者 firewall-cmd --state
  • 端口被占用解决方法:
    1
    2
    3
    4
    # 查看正在使用的端口
    netstat -tanlp
    # 杀死进程
    kill pid

1、简介

Docker是一个开源的应用容器引擎;是一个轻量级容器技术;

Docker支持将软件编译成一个镜像;然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像;

运行中的这个镜像称为容器,容器启动是非常快速的。
docker
windows镜像系统

2、核心概念

docker主机(Host):安装了Docker程序的机器(Docker直接安装在操作系统之上);

docker客户端(Client):连接docker主机进行操作;

docker仓库(Registry):用来保存各种打包好的软件镜像;

docker镜像(Images):软件打包好的镜像;放在docker仓库中;

docker容器(Container):镜像启动后的实例称为一个容器;容器是独立运行的一个或一组应用
核心概念

使用Docker的步骤:

1)、安装Docker

2)、去Docker仓库找到这个软件对应的镜像;

3)、使用Docker运行这个镜像,这个镜像就会生成一个Docker容器;

4)、对容器的启动停止就是对软件的启动停止;

3、安装Docker

1)、安装linux虚拟机(或者使用阿里云服务器)

1)、VMWare、VirtualBox(安装);

2)、导入虚拟机文件;

3)、双击启动linux虚拟机;使用  root/ 123456登陆

4)、使用客户端连接linux服务器进行命令操作;

5)、设置虚拟机网络;

    桥接网络===选好网卡====接入网线;

6)、设置好网络以后使用命令重启虚拟机的网络
1
service network restart
7)、查看linux的ip地址
1
ip addr
8)、使用客户端连接linux;

2)、在linux虚拟机上安装docker

一、配置阿里云yum源(提高docker软件下载速度): 参考连接
1、备份

1
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

2、下载新的CentOS-Base.repo 到/etc/yum.repos.d/
CentOS 7

1
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

或者

1
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

3、生成新的缓存

1
2
3
yum clean all
yum makecache
yum update

二、安装docker步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
1、检查内核版本,必须是3.10及以上
uname -r

2、使用 root 权限登录 Centos。确保 yum 包更新到最新。
yum update

3、卸载旧版本(如果安装过旧版本的话)
$ yum remove docker docker-common docker-selinux docker-engine

4、安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
$ yum install -y yum-utils device-mapper-persistent-data lvm2

5、设置yum源
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

6、可以查看所有仓库中所有docker版本,并选择特定版本安装
$ yum list docker-ce --showduplicates | sort -r

7、安装docker
$ yum install docker-ce-17.12.0.ce #由于repo中默认只开启stable仓库,这里安装的是稳定版17.12.0

8、启动docker
[root@localhost ~] systemctl start docker
[root@localhost ~] docker -v
Docker version 1.12.6, build 3e8e77d/1.12.6

9、开机启动docker
[root@localhost ~] systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

10、停止docker
systemctl stop docker

4、Docker常用命令&操作

1)、镜像操作

操作 命令 说明
检索 docker search 关键字 eg:docker search redis 我们经常去docker hub上检索镜像的详细信息,如镜像的TAG。
拉取 docker pull 镜像名:tag :tag是可选的,tag表示标签,多为软件的版本,默认是latest
列表 docker images 查看所有本地镜像
删除 docker rmi image-id 删除指定的本地镜像

镜像查找: https://hub.docker.com/(包含具体镜像的操作命令)
docker改国内官方镜像(提升镜像pull速度):
编辑文件/etc/docker/daemon.json,没有就新建。加入以下项目

1
2
3
{
"registry-mirrors": ["https://registry.docker-cn.com","http://hub-mirror.c.163.com"]
}

本身daemon.json文件已经有项目,就额外增加registry-mirrors项

重启docker daemon

1
systemctl restart docker

2)、容器操作

软件镜像(QQ安装程序)—-运行镜像—-产生一个容器(正在运行的软件,运行的QQ);

步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1、搜索镜像
[root@localhost ~] docker search tomcat
2、拉取镜像
[root@localhost ~] docker pull tomcat
3、根据镜像启动容器
docker run --name mytomcat -d tomcat:latest
4、docker ps
查看运行中的容器
5、 停止运行中的容器
docker stop 容器的id
6、查看所有的容器(包括没有运行的)
docker ps -a
7、启动容器
docker start 容器id
8、删除一个容器
docker rm 容器id
9、启动一个做了端口映射的tomcat
[root@localhost ~]# docker run -d -p 8888:8080 tomcat
-d:后台运行
-p: 将主机的端口映射到容器的一个端口 主机端口:容器内部的端口

10、为了演示简单关闭了linux的防火墙
service firewalld status ;查看防火墙状态
service firewalld stop:关闭防火墙
11、查看容器的日志
docker logs container-name/container-id

更多命令参看
https://docs.docker.com/engine/reference/commandline/docker/
可以参考每一个镜像的文档

3)、安装MySQL示例

1
docker pull mysql:5.7

正确的启动:做了端口映射

1
2
3
4
5
[root@localhost ~]# docker run -p 3306:3306 --name mysql02 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
ad10e4bc5c6a0f61cbad43898de71d366117d120e39db651844c0e73863b9434
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad10e4bc5c6a mysql "docker-entrypoint.sh" 4 seconds ago Up 2 seconds 0.0.0.0:3306->3306/tcp mysql02

几个其他的高级操作

1
2
3
4
5
6
docker run --name mysql03 -v /conf/mysql:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
把主机的/conf/mysql文件夹挂载到 mysqldocker容器的/etc/mysql/conf.d文件夹里面
改mysql的配置文件就只需要把mysql配置文件放在自定义的文件夹下(/conf/mysql)

docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
指定mysql的一些配置参数

docker安装mysql后外部无法访问,解决办法:

  1. 记得开启阿里云相应的端口号
  2. 修改权限
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    使用bash窗口
    docker exec -it mysqlDB bash

    登陆mysql
    mysql -uroot -p123456;

    修改权限
    > use mysql;
    > update user set authentication_string = password('123456') where user = 'root';
    > grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;
    > flush privileges;
    > exit;

4)、安装redis

1
docker pull redis:5.0.7

正确的启动:做了端口映射

1
2
3
4
5
6
7
8
[root@localhost ~] docker run -d -p 6381:6379 --name myredis  redis:5.0.7 --requirepass "123456"
# --requirepass "123456" 设置密码
# -p 6381:6379:映射容器服务的 6379 端口到宿主机的 681 端口。外部可以直接通过宿主机ip:6381 访问到 Redis 的服务
[root@localhost ~] docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dff3d4e7ef6b redis:5.0.7 "docker-entrypoint.s…" 16 minutes ago Up 16 minutes 0.0.0.0:6381->6379/tcp myredis
[root@localhost ~] docker exec -it myredis bash
#docker exec -it xxx bash 这个命令是表示进入容器的,xxx是服务名称也可以是容器的id

几个其他的高级操作

1
2
3
4
5
6
7
# docker run -p 6382:6379 --name myredis -v $PWD/redis.conf:/etc/redis/redis.conf -v $PWD/data:/data -d redis:5.0.7 redis-server /etc/redis/redis.conf --appendonly yes
  命令说明:
  --name myredis : 指定容器名称,这个最好加上,不然在看docker进程的时候会很尴尬。
  -p 6699:6379 : 端口映射,默认redis启动的是6379,至于外部端口,随便玩吧,不冲突就行。
  -v $PWD/redis.conf:/etc/redis/redis.conf : 将主机中当前目录下的redis.conf配置文件映射。
  -v $PWD/data:/data -d redis:3.2 : 将主机中当前目录下的data挂载到容器的/data
  --redis-server --appendonly yes :在容器执行redis-server启动命令,并打开redis持久化配置\

docker安装redis后外部无法访问,解决办法: 记得开启阿里云相应的端口号.

5)、安装Elasticsearch

参考文章:https://blog.csdn.net/qq_32101993/article/details/100021002
拉取镜像:

1
docker pull elasticsearch:tag(6.8.5)

启动:

1
2
3
4
5
[root@localhost ~] docker run -d  -e  ES_JAVA_OPTS="-Xms256m -Xmx256m"   -p 9200:9200   -p 9300:9300  --name ES01  elasticsearch:版本号(如果是latest则不写) 
[root@localhost ~] docker ps
# 查看是否成功
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3f23945d1ed elasticsearch:6.8.5 "/usr/local/bin/dock…" 6 minutes ago Up 53 seconds 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp ES01

此时已经可以正常外部访问网址:域名:端口号

配置跨域:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1.首先进入容器
docker exec -it ES01 /bin/bash
2.安装vim
yum -y install vim*
3.编辑/config/elasticsearch.ym
vim elasticsearch.yml
4.添加内容
cluster.name: "qfcwx-cluster"
network.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: "*"
5.exit
6.重启
docker restart ES01(容器id或者name)
  1. cluster.name:自定义集群名称。
  2. network.host:当前es节点绑定的ip地址,默认127.0.0.1,如果需要开放对外访问这个属性必须设置。
  3. http.cors.enabled:是否支持跨域,默认为false。
  4. http.cors.allow-origin:当设置允许跨域,默认为*,表示支持所有域名,如果我们只是允许某些网站能访问,那么可以使用正则表达式。

elasticsearch.yml
访问截图:

访问截图

5)、安装rabbitMQ

参考文章:https://www.cnblogs.com/yufeng218/p/9452621.html
拉取镜像:选择带有mangement的版本(包含web管理页面

1
docker pull rabbitmq:management

启动:

1
2
3
4
[root@localhost ~] docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -v `pwd`/data:/var/lib/rabbitmq --hostname myRabbit -e RABBITMQ_DEFAULT_VHOST=my_vhost  -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin 6bd1749b8197
[root@izlnxqoeytyh4fz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c6575d289410 6bd1749b8197 "docker-entrypoint.s…" 6 seconds ago Up 4 seconds 4369/tcp, 5671/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp, 0.0.0.0:15673->5672/tcp rabbitmq
  • -v 映射目录或文件;
  • –hostname 主机名(RabbitMQ的一个重要注意事项是它根据所谓的 “节点名称” 存储数据,默认为主机名);
  • -e 指定环境变量;(RABBITMQ_DEFAULT_VHOST:默认虚拟机名;RABBITMQ_DEFAULT_USER:默认的用户名;RABBITMQ_DEFAULT_PASS:默认用户名的密码)
1
2
# 进入控制台
docker exec -it rabbitmq /bin/bash

此时已经可以正常外部访问网址:域名:端口号

访问截图:
访问截图

何谓悲观锁与乐观锁

乐观锁对应于生活中乐观的人总是想着事情往好的方向发展,悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。这两种人各有优缺点,不能不以场景而定说一种人好于另外一种人。

悲观锁

总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。

乐观锁

总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

两种锁的使用场景

从上面对两种锁的介绍,我们知道两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。

乐观锁常见的两种实现方式

乐观锁一般会使用版本号机制或CAS算法实现。

  1. 版本号机制
    一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。

举一个简单的例子:
假设数据库中帐户信息表中有一个 version 字段,当前值为 1 ;而当前帐户余额字段( balance )为 $100 。

操作员 A 此时将其读出( version=1 ),并从其帐户余额中扣除 $50( $100-$50 )。
在操作员 A 操作的过程中,操作员B 也读入此用户信息( version=1 ),并从其帐户余额中扣除 $20 ( $100-$20 )。
操作员 A 完成了修改工作,将数据版本号加一( version=2 ),连同帐户扣除后余额( balance=$50 ),提交至数据库更新,此时由于提交数据版本大于数据库记录当前版本,数据被更新,数据库记录 version 更新为 2 。
操作员 B 完成了操作,也将版本号加一( version=2 )试图向数据库提交数据( balance=$80 ),但此时比对数据库记录版本时发现,操作员 B 提交的数据版本号为 2 ,数据库记录当前版本也为 2 ,不满足 “ 当前最后更新的version与操作员第一次的版本号相等 “ 的乐观锁策略,因此,操作员 B 的提交被驳回。
这样,就避免了操作员 B 用基于 version=1 的旧数据修改的结果覆盖操作员A 的操作结果的可能。

  1. CAS算法
    即compare and swap(比较与交换),是一种有名的无锁算法。无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。CAS算法涉及到三个操作数
  • 需要读写的内存值 V
  • 进行比较的值 A
  • 拟写入的新值 B

    当且仅当 V 的值等于 A时,CAS通过原子方式用新值B来更新V的值,否则不会执行任何操作(比较和替换是一个原子操作)。一般情况下是一个自旋操作,即不断的重试。