系统结构综合实践-第四次作业(5.18更新)
1.使用Docker-compose实现Tomcat+Nginx负载均衡
(1)docker-compose.yml文件还有nginx配置文件的编写
首先看到本次项目的结构
Tomcat是一个web应用服务器,index.html用于显示登录到服务器上时页面显示的内容,用于区分不同的Tomcat。
docker-compose.yml
version: "3"
services:
nginx:
image: nginx
container_name: ex4ngx
ports:
- "80:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf # 挂载配置文件
depends_on:
- tomcat01
- tomcat02
- tomcat03
tomcat01:
image: tomcat
container_name: ex4tc1
volumes:
- ./tomcat1:/usr/local/tomcat/webapps/ROOT # 挂载web目录
tomcat02:
image: tomcat
container_name: ex4tc2
volumes:
- ./tomcat2:/usr/local/tomcat/webapps/ROOT
tomcat03:
image: tomcat
container_name: ex4tc3
volumes:
- ./tomcat3:/usr/local/tomcat/webapps/ROOT
nginx配置文件
upstream tomcats {
server ex4tc1:8080; # 主机名:端口号
server ex4tc2:8080; # tomcat默认端口号8080
server ex4tc3:8080; # 默认使用轮询策略
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://tomcats; # 请求转向tomcats
}
}
运行docker-compose up并登录到localhost查看配置是否正确
显示的内容为Tomcat1里面index.html的内容,说明配置没有问题 ,可以开始接下来的测试了。
(2)负载均衡测试:轮询策略
由于一遍遍刷新浏览器有点麻烦,在加上Ubuntu的Linux系统自带python3,所以我们编写一个简单的python脚本用于测试负载均衡的轮询策略。
testBalance1.py
import requests
url="http://localhost"
for i in range(0,10):
reponse=requests.get(url)
print(reponse.text)
使用终端运行脚本查看结果
(3)负载均衡测试:权重策略
修改defaul.conf文件然后重启nginx
upstream tomcats {
server ex4tc1:8080 weight=5; # 主机名:端口号
server ex4tc2:8080 weight=3; # tomcat默认端口号8080
server ex4tc3:8080 weight=2; # 默认使用轮询策略
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://tomcats; # 请求转向tomcats
}
}
testBalance2.py
import requests
url="http://localhost"
context={}
for i in range(0,100):
response=requests.get(url)
if response.text in context:
context[response.text]+=1
else:
context[response.text]=1
print(context)
可以看到在100次请求返回的结果中,与我们在nginx配置文件中的权重的比值是基本一致的(5:3:2)。
2.使用Docker搭建大数据集群环境
(1)首先进入到Ubuntu容器中
(2)更新系统源,下载vim和sshd
在bashrc文件末尾加上
/etc/init.d/ssh start
自动开启sshd服务器
(3)配置ssh无密码连接本地sshd服务
ssh-keygen -t rsa #一直按回车键即可
cat id_rsa.pub >> authorized_keys
(4)安装JDK
下载jdk用时接近50分钟,坚持就是胜利,奥里给~
vim ~./bashrc 在文件末尾配置java环境变量
检查环境变量是否配置成功
(5)保存安装完JDK的镜像文件
(6)安装Hadoop
进入到安装好JDK的Ubuntu容器当中
docker run -it -v /home/wayne/ex4-3:/root/build --name ubuntu-jdkinstalled ubuntu/jdkinstalled
# -v 挂载
将预先下载好的压缩包放到创建的目录(容器宿主机共享目录)下以便后续安装
cd /root/build
tar -zxvf hadoop-3.1.3.tar.gz -C /usr/local
cd /usr/local/hadoop-3.1.3
./bin/hadoop version # 验证安装
(7)配置Hadoop集群
先进入配置文件存放目录:
cd /usr/local/hadoop-3.1.3/etc/hadoop
hadoop_env.sh
vim hadoop-env.sh
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ #任意位置添加
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-3.1.3/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
<?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-3.1.3/namenode_dir</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/usr/local/hadoop-3.1.3/datanode_dir</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
</configuration>
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.1.3</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.1.3</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.1.3</value>
</property>
<property>
<name>mapreduce.map.memory.mb</name>
<value>2048</value>
</property>
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>2048</value>
</property>
</configuration>
由于后面运行实例是发现出现内存不足的问题,后面两个property内容是教程中没有的,额外配置的。
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>
<property>
<name>yarn.nodename.vmem-pmem-ratio</name>
<value>2.7</value>
</property>
</configuration>
修改脚本
先进入脚本文件存放目录:
cd /usr/local/hadoop-3.1.3/sbin
在start-dfs.sh和 stop-dfs.sh文件中的function{}后添加:
HDFS_DATANODE_USER=root
HADOOP_SECURE_DN_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root
在start-yarn.sh和 stop-yarn.sh文件中的function{}后添加:
YARN_RESOURCEMANAGER_USER=root
HADOOP_SECURE_DN_USER=yarn
YARN_NODEMANAGER_USER=root
(8)保存配置好Hadoop的Ubuntu容器
(9)运行Hadoop集群
打开三个终端
# 第一个终端
docker run -it -h master --name master ubuntu/hadoopinstalled
# 第二个终端
docker run -it -h slave01 --name slave01 ubuntu/hadoopinstalled
# 第三个终端
docker run -it -h slave02 --name slave02 ubuntu/hadoopinstalled
修改/etc.hosts
为三台主机配置对方的地址信息,他们才能找到彼此。三个终端分别修改/etc/hosts:
vim /etc/hosts # 查看各终端的IP并修改
内容均修改成如下形式即可,多余的可以删去:
172.17.0.2 master
172.17.0.3 slave01
172.17.0.4 slave02
测试ssh
我们可以用如下命令来检测下master是否可以连上slave01和slave02
ssh slave01
ssh slave02
修改workers文件
vim /usr/local/hadoop-3.1.3/etc/hadoop/workers # 旧版为slaves
将localhost修改为:
slave01
slave02
在master节点上
cd /usr/local/hadoop-3.1.3
bin/hdfs namenode -format # 格式化文件系统
sbin/start-dfs.sh # 开启NameNode和DataNode服务
sbin/start-yarn.sh # 开启ResourceManager和NodeManager服务
jps # 查看服务状态
在slave01上:
在slave02上:
说明分布式文件系统hdfs正确的启动了!!!
继续在master节点上输入:
./bin/hdfs dfs -mkdir -p /user/root/input
./bin/hdfs -put ./etc/hadoop/*.xml /user/root/input # 将xml复制到input下,作为示例程序输入
./bin/hdfs dfs -ls /user/root/input
这里说明一下由于后面在测试实例时发现/user/hadoop/input不能正确的找到文件,故改为/user/root/input
这里沿用的是发现这个bug前的图片
(10)运行Hadoop示例程序
./bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.1.jar grep input output 'dfs[a-z.]+' # 运行示例
./bin/hdfs dfs -cat output/*
3. 使用Docker-compose部署javaweb运行环境
使用的是作业博客中提供的项目进行Java-web的部署
修改IP地址
为项目配置nginx反向代理
在原先的docker-compose.yml文件的基础上做一定的修改
version: '3'
services:
tomcat:
image: tomcat:7
hostname: lzz
container_name: lzz
ports:
- "5050:8080"
volumes:
- "$PWD/webapps:/usr/local/tomcat/webapps"
networks:
webnet:
ipv4_address: 15.22.0.15
mymysql:
build: .
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-to-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
然后就可以使用
localhost:8080/ssmgrogshop_war
登录到项目中
登录成功,说明nginx配置没有问题
遇到的问题
1.
显示input的路径错误
解决办法
将/user/hadoop/input目录改为/user/root/input就可以正确的找到路径了
2.
显示所需的虚拟内存不足
解决办法
首先,尝试调高虚拟内存
参考了博客对于yarn-site.xml配置的介绍
https://blog.csdn.net/u010670689/article/details/78204557
加上最后一个property
<property>
<name>yarn.nodename.vmem-pmem-ratio</name>
<value>2.7</value>
</property>
运行之后还是一样的报错,于是调整mapred-site.xml的配置
加上两个property
<property>
<name>mapreduce.map.memory.mb</name>
<value>2048</value>
</property>
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>2048</value>
</property>
参考了博客对于mapred-site.xml配置的介绍
https://www.cnblogs.com/yjt1993/p/9476573.html
这里配置每个map Task和每个reduce Task所需的内存量
配置完成后成功运行!
这里每次调整配置文件时都需要先停止hdfs然后再重新启动,三个节点都要调整
#先停止hdfs
sbin/stop-all.sh
#再重新启动
sbin/start-dfs.sh
sbin/start-yarn.sh
3.
tomcat无法连接到数据库
解决办法:
首先查看数据库的日志:
docker logs 容器名
发现是docker-entrypoint.sh权限不够导致无法登录
接下来回到主目录下,给项目增加权限:
docker-compose down
docker rmi 数据库镜像ID
sudo chmod 777 项目文件夹名
再重新compose-up问题就解决了
总结一哈
1.什么是war包
这是在学习javaweb时查阅资料看到的,觉得写的不错,放在这里。
war是一个可以直接运行的web模块,通常用于网站,打成包部署到容器中。以Tomcat来说,将war包放置在其\webapps\目录下,然后启动Tomcat,这个包就会自动解压,就相当于发布了。
war包是Sun提出的一种web应用程序格式,与jar类似,是很多文件的压缩包。war包中的文件按照一定目录结构来组织。根据其根目录下包含有html和jsp文件,或者包含有这两种文件的目录,另外还有WEB-INF目录。通常在WEB-INF目录下含有一个web.xml文件和一个classes目录,web.xml是这个应用的配置文件,而classes目录下则包含编译好的servlet类和jsp,或者servlet所依赖的其他类(如JavaBean)。通常这些所依赖的类也可以打包成jar包放在WEB-INF下的lib目录下。
简单来说,war包是JavaWeb程序打的包,war包里面包括写的代码编译成的class文件,依赖的包,配置文件,所有的网站页面,包括html,jsp等等。一个war包可以理解为是一个web项目,里面是项目的所有东西。
2.花费的时间
没有具体的计算过
查阅资料+实验+debug+写博客大约用了26小时
(星期一又折腾了一天TAT)