云服务器+docker配置Java程序运行环境
- 一、nginx+jdk
- 二、docker安装
- 三、docker安装mysql
- 3.1使用配置文件启动
- 3.2不使用配置文件创建启动
- 3.3可能遇到的问题
- 3.4查看是否容器状态
- 3.5容器停止/启动/删除
- 3.6容器内连接mysql
- 四、docker安装redis
- 五、docker安装kafka
- 5.1安装
- 5.2问题:宿主机中的java程序无法访问docker中kafka端口
- 5.2.1、端口映射
- 5.2.2、自定义Docker网络
- 5.2.3、使用Docker的host网络模式
- 5.2.4、最终解决
一、nginx+jdk
项目前后端分离部署,安装nginx:
cd /usr/local/
#下载
wget https://nginx.org/download/nginx-1.20.0.tar.gz
#解压
tar zxvf nginx-1.20.0.tar.gz
cd nginx-1.20.0
#配置
./configure
make
sudo make install
#若报错,安装缺失文件后重新执行配置
sudo yum install pcre pcre-devel
./configure
make
sudo make install
#查看运行状态
ps -ef | grep nginx
nginx配置文件参考我的nginx安装启动配置文章。
安装jdk:
参考我的Linux配置Java环境文章,下载安装包
cd /usr/local/tools
#到tools目录下上传安装包之后解压
tar -zxvf jdk-8u172-linux-x64.tar.gz
#在Xshell中输入打开配置文件的命令,回车,按下"i"键进入编辑模式
vi ~/.bashrc
#输入环境配,jdk11没有jre,不需要JRE_HOME
export JAVA_HOME=/usr/local/tools/jdk1.8.0_172
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
export PATH=$PATH:${JAVA_PATH}输入完成后按”Esc“退出编辑,输入":wq"进行保存
#输入命令使配置生效
source ~/.bashrc
#查看版本
java -version
二、docker安装
#安装yum-utils 软件包及其依赖,自动化安装和管理软件包
yum install -y yum-utils
dnf install docker
#启动
systemctl start docker
#自启
sudo systemctl enable docker
配置镜像加速,新建文件命名为daemon.json,并复制以下json代码保存到该文件,注意保留原格式,否则解析可能出问题:
{"registry-mirrors": ["https://0c105db5188026850f80c001def654a0.mirror.swr.myhuaweicloud.com","https://docker.m.daocloud.io","https://noohub.ru","https://huecker.io","https://dockerhub.timeweb.cloud","https://5tqw56kt.mirror.aliyuncs.com","https://docker.1panel.live","http://mirrors.ustc.edu.cn/","http://mirror.azure.cn/","https://hub.rat.dev/","https://docker.ckyl.me/","https://docker.chenby.cn","https://docker.hpcloud.cloud"],"log-driver": "json-file","log-opts": {"max-size": "50m","max-file": "5"}
}
然后将文件上传到指定目录下:
cd /etc/docker
#上传daemon.json文件
#重启docker
systemctl restart docker
三、docker安装mysql
3.1使用配置文件启动
#创建mysql的目录
mkdir -p /usr/local/docker/mysql/{data,config}
#拉取
docker pull mysql:5.7
新建文件my.cnf,并复制以下代码保存到该文件,注意保留原格式:
[client]
# 端口号
port=3306[mysql]
no-beep
default-character-set=utf8mb4[mysqld]
# 端口号
port=3306
# 数据目录
datadir=/var/lib/mysql
# 新模式或表时将使用的默认字符集
character-set-server=utf8mb4
# 默认存储引擎
default-storage-engine=INNODB
# 将 SQL 模式设置为严格
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
# 最大连接数
max_connections=1024
# 表缓存
table_open_cache=2000
# 表内存
tmp_table_size=16M
# 线程缓存
thread_cache_size=10
# 设置大小写不敏感
lower_case_table_names=1# myisam设置
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=8M
key_buffer_size=8M
read_buffer_size=0
read_rnd_buffer_size=0# innodb设置
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=1M
innodb_buffer_pool_size=8M
innodb_log_file_size=48M
innodb_thread_concurrency=33
innodb_autoextend_increment=64
innodb_buffer_pool_instances=8
innodb_concurrency_tickets=5000
innodb_old_blocks_time=1000
innodb_open_files=300
innodb_stats_on_metadata=0
innodb_file_per_table=1
innodb_checksum_algorithm=0# 其他设置
back_log=80
flush_time=0
join_buffer_size=256K
max_allowed_packet=4M
max_connect_errors=100
open_files_limit=4161
sort_buffer_size=256K
table_definition_cache=1400
binlog_row_event_max_size=8K
sync_master_info=10000
sync_relay_log=10000
sync_relay_log_info=10000
然后在启动mysql时加载配置文件:
#切换到配置文件目录
cd /usr/local/docker/mysql/config
#上传文件
#创建容器并启动命令
docker run --name mysql --hostname=mysql --restart=always -p 33442:3306 -e MYSQL_ROOT_PASSWORD=root -v /usr/local/docker/mysql/data:/var/lib/mysql -v /usr/local/docker/mysql/config/my.cnf:/etc/mysql/my.cnf -d mysql:5.7
注:-p 33442:3306进行了端口映射,从外部连接时使用33442端口,如果云主机可开放3306,可以直接使用3306:3306
3.2不使用配置文件创建启动
docker run --name mysql57 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7 --default_authentication_plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --sql-mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
3.3可能遇到的问题
使用navicat可以连接数据库,sql查询报错找不到某张表,但是在navicat中能看到该表存在。
注意启动时配置文件是否加载,大小写敏感等级配置是否正确。
#查看mysql使用的配置
SHOW VARIABLES LIKE 'lower_case_table_names';
#配置文件中,大小写等级
lower_case_table_names=0:表名存储和比较时都区分大小写(类Unix系统默认值)。
lower_case_table_names=1:表名存储为小写,比较时不区分大小写(Windows系统默认值)。
lower_case_table_names=2:表名存储时保持大小写,但比较时不区分大小写(macOS系统上的常见设置)。
3.4查看是否容器状态
#查看docker容器
docker images
#输出如下
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 5107333aaaaa 13 months ago 501MB
#查看运行状态
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
15623b98caca mysql:5.7 "docker-entrypoint.s…" 4 hours ago Up 4 hours 33060/tcp, 0.0.0.0:33442->3306/tcp mysql
3.5容器停止/启动/删除
#一般格式:docker 操作 容器名称/容器ID
#停止
docker stop mysql
#启动
docker start mysql
#删除,慎用,数据也会删掉
docker rm mysql
3.6容器内连接mysql
#第一个mysql使容器名称
docker exec -it mysql mysql -u root -p
#若名称是mysql57则应该使用docker exec -it mysql57 mysql -u root -p
#输入密码,创建容器时没指定密码,此处输入密码就是root
然后进行一些必要的修改,如修改密码,修改后需要flush使配置生效:
alter user 'root'@'%' identified with mysql_native_password by 'aaaaaabbb' password expire never;
flush privileges;
alter user 'root'@'localhost' identified with mysql_native_password by 'aaaaaabbb' password expire never;
flush privileges;
四、docker安装redis
#拉取
docker pull redis
#切换目录
cd /usr/local/docker
#下载配置文件
wget http://download.redis.io/redis-stable/redis.conf
然后将该配置文件通过Xftp等软件传输到本地并修改:
#全文查找requirepass,设置密码,注意格式,例如
requirepass abcdef
#然后全文搜索127,若只本地访问则按照原配置放开
bind 127.0.0.1 -::1
#否则,加#注释掉该配置
#bind 127.0.0.1 -::1
#若修改端口,全文查找6379,修改为其它端口
将修改后的配置文件上传回云主机,覆盖原文件。
docker run -itd -p 6379:6379 --name redis63 -v /usr/local/docker/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/data:/data redis redis-server /etc/redis/redis.conf
若本地需要访问云主机的redis,需要开放6379端口。
五、docker安装kafka
5.1安装
#拉取zookeeper
docker pull wurstmeister/zookeeper
#拉取kafka
docker pull wurstmeister/kafka
# docker images查看容器
#启动zookeeper
docker run -d --name zookeeper --network=host --restart=always --publish 2181:2181 -v /usr/local/docker/zookeeper/data:/data -v /usr/local/docker/zookeeper/conf:/conf -v /usr/local/docker/zookeeper/logs:/datalog --volume /etc/localtime:/etc/localtime wurstmeister/zookeeper
重点在于怎样启动kafka,明确两点:
1.若java程序位于docker容器外,和docker内的kafka通信,二者大概率不在同一个网络
2.若java程序也使用docker容器管理,Java程序才和kafka在同一个网络
#查看是否在同一个网络
ip addr
#输出,注意看eth0表示的宿主机IP和docker0表示的docker的IP
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether fa:......inet 192.168.0.230/24 brd 192.168.0.255 scope global dynamic noprefixroute eth0valid_lft 315080918sec preferred_lft 315080918sec......
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:......inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft forever......
同一个网络下:
root docker run -d --name kafka --restart always --publish 9092:9092 --env KAFKA_ZOOKEEPER_CONNECT=your_ip:2181 --env KAFKA_ADVERTISED_HOST_NAME=your_ip --env KAFKA_ADVERTISED_PORT=9092 --volume /etc/localtime:/etc/localtime wurstmeister/kafka
将your_ip替换为实际IP。
不在同一个网络,看5.2解决。
5.2问题:宿主机中的java程序无法访问docker中kafka端口
在eth0
(宿主机的物理网络接口)和docker0
(Docker的虚拟网桥)不在同一个网络的情况下,部署在宿主机上的Java程序与部署在Docker中的Kafka通信,可以通过以下几种方法实现:
5.2.1、端口映射
- 配置Kafka容器:
- 在启动Kafka容器时,通过
-p
参数将Kafka的监听端口映射到宿主机的某个端口上。 - 例如:
docker run -d --name kafka -p 宿主机端口:9092 ...
- 在启动Kafka容器时,通过
- 配置Java程序:
- 在Java程序中,配置Kafka的连接信息时,使用宿主机的IP地址和映射的端口号。
- 例如:
bootstrap.servers=宿主机IP:宿主机端口
。
5.2.2、自定义Docker网络
- 创建自定义网络:
- 使用
docker network create
命令创建一个自定义的Docker网络。 - 例如:
docker network create my_network
。
- 使用
- 运行Kafka容器:
- 在启动Kafka容器时,通过
--network
参数将其连接到自定义网络。 - 例如:
docker run -d --name kafka --network my_network ...
。
- 在启动Kafka容器时,通过
- 配置宿主机网络:
- 确保宿主机能够访问自定义网络中的容器。这通常意味着宿主机和容器需要在同一个子网内,或者通过路由和NAT规则进行连接。
- 配置Java程序:
- 在Java程序中,配置Kafka的连接信息时,使用Kafka容器在自定义网络中的服务名(如果设置了DNS解析)或IP地址(如果容器有固定的IP地址)。
- 注意:如果容器没有固定的IP地址,可以通过
docker inspect
命令查看容器的网络配置来获取其IP地址。
5.2.3、使用Docker的host网络模式
- 运行Kafka容器:
- 在启动Kafka容器时,使用
--network host
参数将其设置为host网络模式。 - 例如:
docker run -d --name kafka --network host ...
。
注意:在host网络模式下,容器将直接使用宿主机的网络堆栈,这意味着容器将没有自己的IP地址,而是直接使用宿主机的IP地址。因此,这种方法可能会带来安全风险,因为它会绕过Docker的网络隔离机制。
- 在启动Kafka容器时,使用
- 配置Java程序:
- 在Java程序中,配置Kafka的连接信息时,直接使用宿主机的IP地址和Kafka的默认端口
5.2.4、最终解决
将your_ip替换为实际IP。
docker run -d --name kafka --network host -e KAFKA_BROKER_ID=1 -e KAFKA_ZOOKEEPER_CONNECT=localhost:2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://your_ip:9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 wurstmeister/kafka