第四次实践作业
第四次实践作业
一、使用Docker-compose实现Tomcat+Nginx负载均衡
要求:
-
理解nginx反向代理原理;
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器(原始服务器对于客户端是透明的)。而正向代理(Forward Proxy),客户端请求时要指定原始服务器,代理再向原始服务器转交请求并将获得的内容返回给客户端。
-
nginx代理tomcat集群,代理2个以上tomcat;
-
在文件夹中创建如下结构:
-
编辑文件
default.conf
upstream tomcats { server tomcat1:8080 max_fails=3 fail_timeout=30s; server tomcat2:8080 max_fails=3 fail_timeout=30s; server tomcat3:8080 max_fails=3 fail_timeout=30s; } server { listen 80; server_name localhost server; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_pass http://tomcats; proxy_redirect off; } }
docker-compose.yml
version: "3.8" services: nginx: image: nginx container_name: tn_nginx ports: - 8080:80 volumes: - ./nginx/default.conf:/etc/nginx/conf.d/default.conf # 挂载配置文件 depends_on: - tomcat01 - tomcat02 - tomcat03 tomcat01: hostname: tomcat01 image: tomcat container_name: tomcat1 volumes: - ./webapps:/usr/local/tomcat/webapps/ROOT # 挂载web目录 tomcat02: hostname: tomcat02 image: tomcat container_name: tomcat2 volumes: - ./webapps:/usr/local/tomcat/webapps/ROOT # 挂载web目录 tomcat03: hostname: tomcat03 image: tomcat container_name: tomcat3 volumes: - ./webapps:/usr/local/tomcat/webapps/ROOT # 挂载web目录
index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" import="java.net.InetAddress" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Nginx+Tomcat负载均衡</title> </head> <body> <% InetAddress addr = InetAddress.getLocalHost(); out.println("主机名:"+addr.getHostName()); %> </body> </html>
browse.sh
for((i=1;i<=15;i++)); do content=$(curl -s localhost:8080); echo ${content#*<body>}; done
-
运行docker-compose构建容器
-
-
了解nginx的负载均衡策略,并至少实现nginx的2种负载均衡策略;
-
运行 sh browse.sh ,默认方式是轮询访问
-
将default.conf文件修改upstream为
upstream tomcats { server tomcat1:8080 weight=1 max_fails=3 fail_timeout=30s; server tomcat2:8080 weight=2 max_fails=3 fail_timeout=30s; server tomcat3:8080 weight=3 max_fails=3 fail_timeout=30s; }
-
再次运行sh browse.sh,此时使用权重策略,因此访问概率从大到小为tomcat3,tomcat2,tomcat1
-
二、使用Docker-compose部署javaweb运行环境
- 修改文件docker-compose.yml
version: "3" #版本
services: #服务节点
tomcat: #tomcat 服务
image: tomcat #镜像
hostname: hostname #容器的主机名
container_name: tomcat00 #容器名
ports: #端口
- "5050:8080"
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"
#红色的外部访问端口不修改的情况下,要把Linux的MySQL服务停掉
#service mysql stop
#反之,将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 tomcat123 {
server tomcat00:8080;
}
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://tomcat123;
}
}
- ifconfig命令查询本机ip地址
- 在 /webapps/ssmgrogshop_war/WEB-INF/classes/jdbc.properties中修改ip为和端口号
-
docker-compose up -d
-
打开下面任一网址,可以看到登陆界面
http://127.0.0.1:8080/ssmgrogshop_war http://本机ip/ssmgrogshop_war
- 进入后可以进行数据库操作
upstream tomcat123 {
server tomcat00:5050;
server tomcat01:5051;
}
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://tomcat123;
}
}
- 修改nginx配置文件default.conf,反向代理tomcat
upstream tomcats {
server tomcat00:5050;
server tomcat01:5051;
}
-
修改yml文件
version: "3" #版本 services: #服务节点 tomcat00: #tomcat 服务 image: tomcat #镜像 hostname: hostname #容器的主机名 container_name: tomcat00 #容器名 ports: #端口 - "5050:8080" volumes: #数据卷 - "./webapps:/usr/local/tomcat/webapps" - ./wait-for-it.sh:/wait-for-it.sh networks: #网络设置静态IP webnet: ipv4_address: 15.22.0.15 tomcat01: #tomcat 服务 image: tomcat #镜像 hostname: hostname #容器的主机名 container_name: tomcat01 #容器名 ports: #端口 - "5055:8080" volumes: #数据卷 - "./webapps:/usr/local/tomcat/webapps" - ./wait-for-it.sh:/wait-for-it.sh networks: #网络设置静态IP webnet: ipv4_address: 15.22.0.16 mymysql: #mymysql服务 build: . #通过MySQL的Dockerfile文件构建MySQL image: mymysql:test container_name: mymysql ports: - "3309:3306" #红色的外部访问端口不修改的情况下,要把Linux的MySQL服务停掉 #service mysql stop #反之,将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 depends_on: - tomcat00 - tomcat01 networks: webnet: ipv4_address: 15.22.0.7 networks: #网络设置 webnet: driver: bridge #网桥模式 ipam: config: - subnet: 15.22.0.0/24 #子网
-
随后可以分别通过5050和5051端口访问,达到负载均衡
三、使用Docker搭建大数据集群环境
1.要求
直接用机器搭建Hadoop集群,会因为不同机器配置等的差异,遇到各种各样的问题;也可以尝试用多个虚拟机搭建,但是这样对计算机的性能要求比较高,通常无法负载足够的节点数;使用Docker搭建Hadoop集群,将Hadoop集群运行在Docker容器中,使Hadoop开发者能够快速便捷地在本机搭建多节点的Hadoop集群。
2.相关环境配置
-
拉取ubuntu镜像 docker pull ubuntu
-
运行镜像并与本地
/home/xiaoc/build
文件夹共享 -
ubuntu系统初始化并安装升级必要软件 apt-get update && apt-get install vim && apt-get install ssh
-
设置ssd开机启动,vim ~/.bashrc 在文末添加 /etc/init.d/ssh start
-
设置ssh免密码登陆
cd ~/.ssh ssh-keygen -t rsa cat id_rsa.pub >> authorized_keys
-
测试ssh
-
安装JDK1.8
apt-get install openjdk-8-jdk
-
安装hadoop
docker cp ./build/hadoop-3.1.3.tar.gz 容器ID:/root/hadoop-3.1.3.tar.gz cd /root tar -zxvf hadoop-3.1.3.tar.gz -C /usr/local
-
vim ~/.bashrc,在文末加入以下,配置java和hadoop环境
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ export PATH=$PATH:$JAVA_HOME/bin export HADOOP_HOME=/usr/local/hadoop-3.1.3 export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin:$JAVA_HOME/bin
source ~/.bashrc # 使.bashrc生效
-
验证是否安装成功
3.配置hadoop集群
(1)cd /usr/local/hadoop-3.1.3/etc/hadoop 进入配置目录,修改以下文件
- 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.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>
<property>
<name>dfs.permissions.enabled</name>
<value>false</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>
</configuration>
- yarn-site.xml
<?xml version="1.0" ?>
<configuration>
<!-- Site specific YARN configuration properties -->
<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.nodemanager.vmem-pmem-ratio</name>
<value>2.5</value>
</property>
</configuration>
(2)cd /usr/local/hadoop-3.1.3/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
4.构建镜像并运行主机,开启三个中断分别运行
docker commit 容器ID ubuntu/hadoop
# 第一个终端
docker run -it -h master --name master ubuntu/hadoop
# 第二个终端
docker run -it -h slave1 --name slave01 ubuntu/hadoop
# 第三个终端
docker run -it -h slave2 --name slave02 ubuntu/hadoop
-
根据各个容器的ip分别修改/etc/hosts
-
测试ssh
-
vim /usr/local/hadoop-3.1.3/etc/hadoop/workers 在master的workers中加入
slave1 slave2
-
master上开启服务,运行
start-dfs.sh start-yarn.sh
5.运行示例程序
-
放置输入文件
./bin/hdfs dfs -mkdir -p /user/root/input && ./bin/hdfs dfs -put ./etc/hadoop/*.xml input && ./bin/hdfs dfs -ls /user/root/input
-
执行实例程序
./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.1.jar grep input output 'dfs[a-z.]+'
-
获取输出内容
hdfs dfs -cat output/*
四、总结及踩过的坑
1.总计时间:2天
2.踩过的坑:运行sh脚本的时候显示Syntax error: Bad for loop variable,思考了很久也找不到语法错误。查询后发现,ubuntu使用的是dash shell,所以解决方法是将默认的shell更改为bash。
sudo dpkg-reconfigure dash