2020系统综合实践 第4次实践作业
(1)使用Docker-compose实现Tomcat+Nginx负载均衡
要求:
- 理解nginx反向代理原理;
- nginx代理tomcat集群,代理2个以上tomcat;
- 了解nginx的负载均衡策略,并至少实现nginx的2种负载均衡策略;
参考资料:
nginx反向代理
多个客户端给服务器发送的请求,nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。此时~请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,nginx扮演的就是一个反向代理角色。
文件夹如图
树形如图
Docker-compose.yml
`version: "3.1"`
`services:`
`nginx:`
`image: nginx`
`container_name: ng1`
`ports:`
`\- 80:2508`
`volumes:`
`\- ./nginx/default.conf:/etc/nginx/conf.d/default.conf # 挂载配置文件`
`depends_on:`
`\- tomcat01`
`\- tomcat02`
`\- tomcat03`
````
`tomcat01:`
`image: tomcat`
`container_name: tt1`
`volumes:`
`\- ./tomcat/tomcat1:/usr/local/tomcat/webapps/ROOT # 挂载web目录`
````
`tomcat02:`
`image: tomcat`
`container_name: tt2`
`volumes:`
`\- ./tomcat/tomcat2:/usr/local/tomcat/webapps/ROOT`
````
`tomcat03:`
`image: tomcat`
`container_name: tt3`
`volumes:`
`\- ./tomcat/tomcat3:/usr/local/tomcat/webapps/ROOT`
第一种负载均衡策略(轮询方式)
Nginx配置文件dafault.conf
sudo docker-compose up -d –build
第二种负载均衡方式(权重方式)
Nginx配置文件dafault.conf
sudo docker-compose down
sudo docker-compose up -d –build
(2) 使用Docker-compose部署javaweb运行环境
要求:
- 分别构建tomcat、数据库等镜像服务;
- 成功部署Javaweb程序,包含简单的数据库操作;
- 为上述环境添加nginx反向代理服务,实现负载均衡。
参考资料:
本次参考老师给出的资料。
文件夹如图
Dockerfile
# 这个是构建MySQL的dockerfile
FROM registry.saas.hand-china.com/tools/mysql:5.7.17
# mysql的工作位置
ENV WORK_PATH /usr/local/
# 定义会被容器自动执行的目录
ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d
#复制gropshop.sql到/usr/local
COPY grogshop.sql /usr/local/
#把要执行的shell文件放到/docker-entrypoint-initdb.d/目录下,容器会自动执行这个shell
COPY docker-entrypoint.sh $AUTO_RUN_DIR/
#给执行文件增加可执行权限
RUN chmod a+x $AUTO_RUN_DIR/docker-entrypoint.sh
# 设置容器启动时执行的命令
#CMD ["sh", "/docker-entrypoint-initdb.d/import.sh"]
docker-compose.yml
version: "3"
services:
tomcat00:
image: tomcat
hostname: hostname
container_name: tomcat00
ports:
- "5050:8080" #后面访问网页的时候要选择对应的端口号5050
volumes: #数据卷
- "./webapps:/usr/local/tomcat/webapps"
- ./wait-for-it.sh:/wait-for-it.sh
networks: #网络设置静态IP
webnet:
ipv4_address: 15.22.0.15
mymysql: #mymysql服务
build: . #通过MySQL的Dockerfile文件构建MySQL
image: mymysql:test
container_name: mymysql
ports:
- "3309:3306"
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_unicode_ci'
]
environment:
MYSQL_ROOT_PASSWORD: "123456"
networks:
webnet:
ipv4_address: 15.22.0.6
nginx:
image: nginx
container_name: "nginx-tomcat"
ports:
- 8080:8080
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf # 挂载配置文件
tty: true
stdin_open: true
networks:
webnet:
ipv4_address: 15.22.0.7
networks: #网络设置
webnet:
driver: bridge #网桥模式
ipam:
config:
-
subnet: 15.22.0.0/24 #子网
default.conf
upstream tomcats {
server tomcat00:5050;
}
server {
listen 8080
server_name localhost;
location / {
proxy_pass http://tomcat123;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
docker-entrypoint.sh
#!/bin/bash
mysql -uroot -p123456 << EOF
source /usr/local/grogshop.sql;
jdbc.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://172.22.0.1:3309/grogshop?useUnicode=true&characterEncoding=utf-8
username=root
password=123456
docker-compose up -d --build
使用反向代理
修改default.conf
upstream tomcats{
server tt1:8080 ;
server tt2:8080 ;
server tt3:8080 ;
}
server {
listen 2508;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
proxy_pass http://tomcats;
}
}
修改docker-compose.yml
version: "3"
services:
tomcat00:
image: tomcat
hostname: hostname
container_name: tomcat00
ports:
- "5050:8080" #后面访问网页的时候要选择对应的端口号5050
volumes: #数据卷
- "./webapps:/usr/local/tomcat/webapps"
- ./wait-for-it.sh:/wait-for-it.sh
networks: #网络设置静态IP
webnet:
ipv4_address: 15.22.0.15
mymysql: #mymysql服务
build: . #通过MySQL的Dockerfile文件构建MySQL
image: mymysql:test
container_name: mymysql
ports:
- "3309:3306"
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_unicode_ci'
]
environment:
MYSQL_ROOT_PASSWORD: "123456"
networks:
webnet:
ipv4_address: 15.22.0.6
nginx:
image: nginx
container_name: "nginx-tomcat"
ports:
-8080:8080
volumes:
-./default.conf:/etc/nginx/conf.d/default.conf # 挂载配置文件
tty:true
stdin_open: true
networks:
webnet:
ipv4_address: 15.22.0.7
depends_on:
- tomcat00
- tomcat01
- tomcat02
tomcat01:
image: tomcat
hostname: hostname
container_name: tomcat01
ports:
-"5051:8080" #后面访问网页的时候要选择对应的端口号5050
volumes: #数据卷
-"./webapps:/usr/local/tomcat/webapps"
- ./wait-for-it.sh:/wait-for-it.sh
networks: #网络设置静态IP
webnet:
ipv4_address: 15.22.0.16
tomcat02:
image: tomcat
hostname: hostname
container_name: tomcat02
ports:
- "5052:8080" #后面访问网页的时候要选择对应的端口号5050
volumes: #数据卷
- "./webapps:/usr/local/tomcat/webapps"
- ./wait-for-it.sh:/wait-for-it.sh
networks: #网络设置静态IP
webnet:
ipv4_address: 15.22.0.17
networks: #网络设置
webnet:
driver: bridge #网桥模式
ipam:
config:
- subnet: 15.22.0.0/24 #子网
重新构造
使用5050.5051.5052端口均可访问
(3)使用Docker搭建大数据集群环境
直接用机器搭建Hadoop集群,会因为不同机器配置等的差异,遇到各种各样的问题;也可以尝试用多个虚拟机搭建,但是这样对计算机的性能要求比较高,通常无法负载足够的节点数;使用Docker搭建Hadoop集群,将Hadoop集群运行在Docker容器中,使Hadoop开发者能够快速便捷地在本机搭建多节点的Hadoop集群。
要求:
- 完成hadoop分布式集群环境配置,至少包含三个节点(一个master,两个slave);
- 成功运行hadoop 自带的测试实例。
参考资料:
首先这是本次实验的各镜像等工具的使用版本
- Docker容器环境:
Ubuntu 16.04
- JDK版本:
openjdk 1.8.0_252
- Hadoop版本:
Hadoop 3.2.1
首先创建ubuntu
Dockerfile
FROM ubuntu:16.04
COPY ./sources.list /etc/apt/sources.list
sources.list
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe multiverse
# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security main restricted universe multiverse
# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-proposed main restricted universe multiverse
# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-proposed main restricted universe multiverse
docker build -t ubuntu .
启动对ubuntu进行配置
docker run -it --name ubuntu ubuntu
apt-get update
更新系统软件源
apt-get install vim
安装下经常会使用到的vim软件
apt-get install ssh
apt-get install sudo
安装sshd,因为在开启分布式Hadoop时,需要用到ssh连接slave:。
运行如下脚本即可开启sshd服务器:
/etc/init.d/ssh
这启动命令写进~/.bashrc文件,这样我们每次登录Ubuntu系统时,都能自动启动sshd服务;
vim ~/.bashrc
在该文件中最后一行添加如下内容:
/etc/init.d/ssh start
免密码ssh设置
cd ~/.ssh
ssh-keygen -t rsa
# 一直按回车即可
cat id_rsa.pub >> authorized_keys
#apt-get默认安装的是JDK11,而Hadoop 3.x目前仅支持Java 8,2.x支持Java 7/8.JDK版本太高的原因,可能会出现版本依赖的各种问题。
apt-cache search jdk
apt-get install openjdk-8-jdk vim ~/.bashrc
在文件末尾添加以下两行,配置Java环境变量:
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ export PATH=$PATH:$JAVA_HOME/bin source
~/.bashrc
# 使.bashrc生效
存档并下载hadoop准备安装
docker ps # 查看当前容器id
docker commit 容器ID ubuntu/jdk8 # 存档
docker run -it -v /home/ubuntu/ubuntu/hadoop/build:/root/build --name ubuntu-jdk8 ubuntu/jdk8
cd /root/build
tar -zxvf hadoop-3.2.1.tar.gz -C /usr/local #解压缩
cd /usr/local/hadoop-3.2.1
./bin/hadoop version # 验证安装
配置hadoop
#先进入配置文件存放目录:
cd /usr/local/hadoop-3.2.1/etc/hadoop
hadoop-env.sh
vim hadoop-env.sh
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ # 在任意位置添加
core-site.xml
vim core-site.xml
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl" ?>
<configuration>
<property>
<name>hadoop.tmp.dir</name>
<value>file:/usr/local/hadoop/tmp</value>
<description>Abase for other temporary directories.</description>
</property>
<property>
<name>fs.defaultFS</name>
<value>hdfs://master:9000</value>
</property>
</configuration>
hdfs-site.xml
vim hdfs-site.xml
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl" ?>
<configuration>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/usr/local/hadoop/namenode_dir</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/usr/local/hadoop/datanode_dir</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
</configuration>
mapred-site.xml
vim mapred-site.xml
<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl" ?>
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.2.1</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.2.1</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.2.1</value>
</property>
</configuration>
yarn-site.xml
vim yarn-site.xml
<?xml version="1.0" ?>
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>master</value>
</property>
</configuration>
修改脚本
进入脚本文件存放目录:
cd /usr/local/hadoop-3.2.1/sbin
对于start-dfs.sh
和stop-dfs.sh
文件,添加下列参数:
HDFS_DATANODE_USER=root
HADOOP_SECURE_DN_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root
对于start-yarn.sh
和stop-yarn.sh
,添加下列参数:
YARN_RESOURCEMANAGER_USER=root
HADOOP_SECURE_DN_USER=yarn
YARN_NODEMANAGER_USER=root
PS:注意放在合适的位置,比如function{}
之后。
做完以上步骤之后另开一个终端存个档:
docker commit 容器ID ubuntu/hadoop # 存档
运行hadoop集群
#用上面存档的镜像开启三个终端,分别运行集群中的主机:
# 第一个终端
docker run -it -h master --name master ubuntu/hadoop
# 第二个终端
docker run -it -h slave01 --name slave01 ubuntu/hadoop
# 第三个终端
docker run -it -h slave02 --name slave02 ubuntu/hadoop
配置三台主机的地址信息
vim /etc/hosts # 查看各终端的IP,并根据ip修改
测试,使用ssh来访问目标主机
ssh slave01
ssh slave02
再修改
vim /usr/local/hadoop-3.2.1/etc/hadoop/workers # 旧版为slaves
\#将localhost修改为
slave01 slave02
在master主机上,进行测试:
cd /usr/local/hadoop-3.2.1
bin/hdfs namenode -format # 格式化文件系统
sbin/start-dfs.sh # 开启NameNode和DataNode服务
bin/hdfs dfs -mkdir /user # 建立HDFS文件夹,也可以放到下面示例程序中进行
bin/hdfs dfs -mkdir /user/root
bin/hdfs dfs -mkdir input
bin/hdfs dfs -put etc/hadoop/*.xml input # 将xml复制到input下,作为示例程序输入
sbin/start-yarn.sh # 开启ResourceManager和NodeManager服务
jps # 查看服务状态
在master上:
bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.1.jar grep input output 'dfs[a-z.]+' # 运行示例
bin/hdfs dfs -get output output # 获取输出结果
cat output/* # 查看输出结果
sbin/stop-all.sh # 停止所有服务
结果如图
(4)总结
第一个实验:
第一个实验大概花费了4个小时,看资料看的时间花的不是很多,因为轮询啊权重,计网课都有接触过,主要的错误来源于配置的错误。host not found in upstream "mytomcat1:8080" in /etc/nginx/conf.d/default.conf:2
第二个实验:
第二个实验对于一个没有接触过任何java的人,有点不知道从何下手,然后我看了很久很久javaweb的一些资料+视频,最后选择按老师给的教程里做(。,看资料大概看了挺久的因为视频啥啥的,做的没有很久,大概花了5,6个小时。
第三个实验:
第三个实验也太不知所云了,因为我理论基础没有很强,虽然老师给的资料也很详细,里面步骤也写的很清楚,但是我还是在很多很多地方不停的出错
执行 cd ~/.ssh发现ssh目录找不到
1 2 | [root@ocdp2 ~]# cd ~/.ssh -bash: cd: /root/.ssh: No such file or directory |
---|---|
原因是因为没有用root用户ssh登录过,执行一下ssh操作就会自动生成了
packet_write_wait: Connection to 127.0.0.1 port 22: Broken pipe
的问题,可能应该是ip 的地方弄错了。
还有这个错误,salve02无法连上,后面又重新检查了一下也是IP的问题。
大概花费了7,8个小时。
写博客2小时。
我太菜了,我真的太菜了,补习理论知识的时间太久了呜呜呜,感觉10天过的好快,拖延症真的太难了,在家学习真的太充满未知了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?