系统结构综合实践-第四次作业(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)

原文地址:https://www.cnblogs.com/WAYNEEZHONG/p/12891626.html