第4次系统综合实践作业

使用Docker-compose实现Tomcat+Nginx负载均衡

1.nginx反向代理原理

反向代理服务器架设在服务器端,通过缓冲经常被请求的页面来缓解服务器的工作量,将客户机请求转发给内部网络上的目标服务器;并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器与目标主机一起对外表现为一个服务器。

2.nginx代理tomcat集群,代理2个以上tomcat

(1)项目结构

.
├── docker-compose.yml
├── nginx
│   └── default.conf
├── tomcat1
│   └── index.html
├── tomcat2
│   └── index.html
└── tomcat3
    └── index.html

(2)相关文件编写

  • default.conf文件
upstream tomcats {
        server tct1:8080 ;
        server tct2:8080 ;
        server tct3:8080 ;
}
   
server {
        listen 2313;
        server_name localhost;
         
        location / {
             root   /usr/share/nginx/html;
             index  index.html index.htm;
             proxy_pass http://tomcats;
        }
}
  • docker-compose.yml文件
version: "3.8"
services:
    nginx:
        image: nginx
        container_name: tngx
        ports:
            - 80:2313
        volumes:
            - ./nginx/default.conf:/etc/nginx/conf.d/default.conf # 挂载配置文件
        depends_on:
            - tomcat1
            - tomcat2
            - tomcat3

    tomcat1:
        image: tomcat
        container_name: tct1
        volumes:
            - ./tomcat1:/usr/local/tomcat/webapps/ROOT # 挂载web目录

    tomcat2:
        image: tomcat
        container_name: tct2
        volumes:
            - ./tomcat2:/usr/local/tomcat/webapps/ROOT

    tomcat3:
        image: tomcat
        container_name: tct3
        volumes:
            - ./tomcat3:/usr/local/tomcat/webapps/ROOT

(3)执行docker-compose.yml文件

sudo docker-compose up -d

3.添加nginx反向代理服务,实现负载均衡

(1)轮询策略(默认策略)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
测试:

import requests

url='http://localhost'
for i in range(0,6):
    response=requests.get(url)
    print(response.text)

测试成功,结果如下:

按照3 1 2的顺序依次访问。
(2)weight策略(权重策略)
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
需要修改default.conf配置文件:

upstream tomcats {
        server tct1:8080 weight=1;
        server tct2:8080 weight=2;
        server tct3:8080 weight=3;
}

测试:

import requests

url = 'http://localhost'
count={}
for i in range(0,30):
    response=requests.get(url)

    if response.text in count:
         count[response.text] += 1
    else:
         count[response.text] = 0
    print(response.text)
print(count)

测试成功,测试结果如下:

其中Tomcat1、Tomcat2、Tomcat3分别以1:2:3的比例被进行访问

使用Docker-compose部署javaweb运行环境

1.项目结构

.
├── default.conf
├── docker-compose.yml
├── docker-entrypoint.sh
├── Dockerfile
├── grogshop.sql
└── webapps

2.相关文件编写

  • default.conf文件
upstream tomcats {
    server tomcat00:8080;
    server tomcat01:8080;
}

server {
    listen 2313;
    server_name localhost;
 
    location / {
        root /usr/share/nginx/html;
        index index.html index.html;
        proxy_pass http://tomcats;
    }
}
  • 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
#复制grogshop.sql到/usr/local
COPY grogshop.sql /usr/local/
#复制要执行的shell文件到/docker-entrypoint-initdb.d/目录下
COPY docker-entrypoint.sh $AUTO_RUN_DIR/
#给执行文件增加可执行权限
RUN chmod a+x $AUTO_RUN_DIR/docker-entrypoint.sh
  • docker-compose文件
version: "3"
services:
   tomcat00:
       image: tomcat
       container_name: tomcat00
       volumes:
        - "./webapps:/usr/local/tomcat/webapps"
       networks:
         webnet:
            ipv4_address: 15.22.0.15
   tomcat01:
       image: tomcat
       container_name: tomcat01
       volumes:
        - "./webapps:/usr/local/tomcat/webapps"
       networks:
         webnet:
            ipv4_address: 15.22.0.16
   mymysql:
       build: .
       image: mysql
       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:
         - 80:2313
       volumes:
         - ./default.conf:/etc/nginx/conf.d/default.conf
       depends_on:
         - tomcat00
         - tomcat01
       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
           
  • docker-entrypoint.sh文件
#!/bin/bash
mysql -uroot -p123456 << EOF
source /usr/local/grogshop.sql;

借用教程里的Javaweb项目,并修改连接数据库的ip
webapps/ssmgrogshop_war/WEB-INF/classes/jdbc.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://10.0.2.15:3309/grogshop?useUnicode=true&characterEncoding=utf-8
username=root
password=123456

3.执行docker-compose文件

sudo docker-compose up -d

4.浏览器访问页面(localhost/ssmgrogshop_war/)

进入登录页面(登录名sa,密码123)

登录之后进行插入操作

  • 查询操作
  • 插入操作



使用Docker搭建大数据集群环境

1.pull Ubuntu镜像并在本地创建工作目录

sudo docker pull ubuntu
cd ~
mkdir build
sudo docker run -it -v /home/monster/build:/root/build --name ubuntu ubuntu

其中,build文件夹用来本地与Ubuntu容器进行共享文件

2.Ubuntu容器初始化

  • 更新软件源
apt-get update
  • 安装vim(便于在容器中编辑文件)
apt-get install vim
  • 安装ssh(在开启分布式Hadoop时,需要用到ssh连接slave节点)
apt-get install ssh
  • 开启sshd服务器:
/etc/init.d/ssh start     # 运行脚本即可开启sshd服务器
vim ~/.bashrc             
/etc/init.d/ssh start  # 在该文件中最后一行添加如下内容,实现进入Ubuntu系统时,都能自动启动sshd服务
  • 配置ssh
cd ~/.ssh
ssh-keygen -t rsa #一直按回车即可
cat id_rsa.pub >> authorized_keys 
  • 安装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生效
  • 保存新镜像文件
sudo docker commit 容器ID ubuntu:jdk8      jkd8版本的ubuntu

sudo docker run -it -v /home/monster/build:/root/build --name ubuntu-jdk8 ubuntu:jdk8   #开启保存镜像ubuntu:jdk8容器

3.安装Hadoop

cd /root/build
#将hadoop压缩包放入本地build文件夹中,这里使用大数据实验中的3.1.3版本
tar -zxvf hadoop-3.1.3.tar.gz -C /usr/local 
cd /usr/local/hadoop-3.1.3
./bin/hadoop version # 验证安装

4.配置Hadoop

  • 进入工作目录
cd /usr/local/hadoop-3.1.3/etc/hadoop 
  • hadoop-env.sh文件(修改JAVA_HOME)
vim hadoop-env.sh
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ # 在任意位置添加
  • core-site.xml文件
<configuration>
    <property>  
        <name>fs.defaultFS</name>
        <value>hdfs://master:9000</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>file:/usr/local/hadoop-3.1.3/tmp</value>
	<description>A base for other temporary directories.</description>
    </property>
</configuration>

  • hdfs-site.xml文件
<configuration>
        <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:/usr/local/hadoop-3.1.3/tmp/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:/usr/local/hadoop-3.1.3/tmp/dfs/data</value>
    </property>
</configuration>

  • mapred-site.xml文件
<configuration>
	<property>
		<name>mapreduce.framework.name</name>
		<value>yarn</value>
	</property>
	<property>
		<name>mapreduce.jobhistory.address</name>
		<value>master:10020</value>
	</property>
	<property>
		<name>mapreduce.jobhistory.webapp.address</name>
		<value>master:19888</value>
	</property>
	<property>
		<name>mapreduce.application.classpath</name>
		<value>/usr/local/hadoop-3.1.3/share/hadoop/mapreduce/lib/*,/usr/local/hadoop-3.1.3/share/hadoop/mapreduce/*</value>
	</property>
</configuration>

  • yarn-site.xml文件
<configuration>
	<property>
		<name>yarn.resourcemanager.hostname</name>
		<value>master</value>
	</property>
	<property>
		<name>yarn.nodemanager.aux-services</name>
		<value>mapreduce_shuffle</value>
	</property>
	<property>
		<name>yarn.nodemanager.vmem-pmem-ratio</name>
		<value>2.5</value>
	</property>
</configuration>

  • 对于start-dfs.sh和stop-dfs.sh文件
cd /usr/local/hadoop-3.1.3/sbin

添加一下参数:

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

  • 再次保存镜像
sudo docker commit 容器id ubuntu/hadoop
  • 分别打开三个终端,运行ubuntu/hadoop容器
# 第一个终端
sudo docker run -it -h master --name master ubuntu/hadoop
# 第二个终端
sudo docker run -it -h slave01 --name slave01 ubuntu/hadoop
# 第三个终端
sudo docker run -it -h slave02 --name slave02 ubuntu/hadoop

  • 三个终端分别查看/etc/hosts,get各自的IP
cat /etc/hosts
  • 将三个终端的地址分别在添加到各自的/etc/hosts文件中
172.17.0.4      master
172.17.0.5      slave01
172.17.0.6      slave02
  • 在master节点终端检测下master是否可以连上slave01和slave02
ssh slave01
ssh slave02
exit   #连接上slave节点后从slave节点退回master节点


  • 修改workers文件
#将localhost替换为以下两行
slave01
slave02

5.启动Hadoop集群

  • 在master终端上,首先进入/usr/local/hadoop-3.1.3
  • 格式化并启动hadoop
cd /usr/local/hadoop-3.1.3
bin/hdfs namenode -format      #首次启动Hadoop需要格式化
sbin/start-all.sh              #启动Hadoop


  • 运行命令jps查看运行结果
    master节点:

    slave01节点:

    slave02节点:

    启动成功!!

6.运行grep实例

  • 在hdfs中创建input文件夹并将容器本地的文件上传到input中
bin/hdfs dfs -mkdir /user/root/input
bin/hdfs dfs -put ./etc/hadoop/*.xml /user/root/input

  • 验证文件是否上传成功
bin/hdfs dfs -ls input

  • 运行grep实例
./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar grep /user/hadoop/input output 'dfs[a-z.]+'
  • 在hdfs上的output目录下查看到运行结果
./bin/hdfs dfs -cat output/*

  • 关闭hadoop
sbin/stop-all.sh


四、遇到的问题及解决方法

问题1.在实验一nginx反向代理Tomcat中,浏览器连接不到网页
解决方法:找了半天,才发现是nginx没有配置好,端口没有映射好。
问题2.在实验三中第二次保存镜像时,虚拟机报错自己暂停,无法使用
解决方法:还好做之前有clone过虚拟机,不然凉凉啊。查看报错,发现是虚拟机存放的本地磁盘空间不足保存十几个G的镜像,所以一切又得重头开始,哭了。
问题3.当再次启动hadoop时,没有jps查看,导致hdfs上传文件时报错

解决方法:查看报错显示0个DataNode,所以又重新jps三个节点,才发现两个slave节点没有DataNode。查找博客,才知道原来我又重新格式化了一次namenode导致DataNode的ID不符,所以需要找到配置文件hdfs-site.xml中data存放目录,然后关闭hadoop并在三个节点中删除data文件夹下的所有内容,重新format,解决:)

五、实验心得

这次实验用时很久,不过也让我又一次体会到了docker的强大,尤其是在hadoop实验中。因为之前在大数据实验课中有在虚拟机上搭建hadoop完全分布式配置,当时运行hadoop实例电脑卡死,发现对性能要求很高。但是这次不一样,在docker容器上运行更加方便快捷,并能可以搭建多个节点的hadoop集群,真的无比感叹。对于Javaweb项目,真的是之前没有接触过,时间有点紧张,所以借用了教程中的项目。同时也了解到nginx反向代理的原理和实现负载均衡。

猜你喜欢

转载自www.cnblogs.com/lrongblog/p/12909903.html