1 使用Docker-compose实现Tomcat+Nginx负载均衡
1.1 理解nginx反向代理原理
Http代理,反向代理:作为web服务器最常用的功能之一,尤其是反向代理。
Nginx在做反向代理时,提供性能稳定,并且能够提供配置灵活的转发功能。Nginx可以根据不同的正则匹配,采取不同的转发策略,比如图片文件结尾的走文件服务器,动态页面走web服务器,只要你正则写的没问题,又有相对应的服务器解决方案,你就可以随心所欲的玩。并且Nginx对返回结果进行错误页跳转,异常判断等。如果被分发的服务器存在异常,他可以将请求重新转发给另外一台服务器,然后自动去除异常服务器。
----------------------------------------------------------------------------------------
参考自https://www.runoob.com/w3cnote/nginx-setup-intro.html
1.2 nginx代理tomcat集群,代理2个以上tomcat
- 文件树
- default.conf内容
upstream tomcats { server tomcat01:8080; #服务器名为docker-compose.yml的各个服务器 server tomcat02:8080; #端口号随便都可 server tomcat03:8080; } server { listen 11234; server_name localhost; location / { proxy_pass http://tomcats; # 请求转向tomcats } }
- docker-compose.yml内容
version: "3" services: nginx: image: nginx ports: - "7890:11234" volumes: - ./default.conf:/etc/nginx/conf.d/default.conf depends_on: - tomcat01 - tomcat02 - tomcat03 tomcat01: image: tomcat volumes: - ./web:/usr/local/tomcat/webapps/ROOT tomcat02: image: tomcat volumes: - ./web:/usr/local/tomcat/webapps/ROOT tomcat03: image: tomcat volumes: - ./web:/usr/local/tomcat/webapps/ROOT
- index.jsp或者index.html都可,内容按自己的喜好
1.3 了解nginx的负载均衡策略,并至少实现nginx的2种负载均衡策略
1.3.1轮询
最基本的配置方法,上面的例子就是轮询的方式,它是upstream模块默认的负载均衡默认策略。每个请求会按时间顺序逐一分配到不同的后端服务器。
- 将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.getHostAddress()); out.println("主机名:"+addr.getHostName()); %> </body> </html>
- 因为默认就是采用轮询策略,所以跟其他的不变
- 访问localhost:7890 每次刷新都会不一样,说明使用了不同服务器
1.3.2 weight
采用不同的权重分配服务器,权重越高被访问的几率越大。适用于设备性能有差异的情况下使用。
- 修改default.conf
2. 使用Docker-compose部署javaweb运行环境
2.1分别构建tomcat、数据库等镜像服务
2.2成功部署Javaweb程序,包含简单的数据库操作
由于实在懂javaweb的原理但是自己写不知道要写什么而且一大堆api学起来太麻烦就直接用老师给的参考博客内的例子(所以两个一起做了)
- 打开webapps/ssmgrogshop_war/WEB-INF/classes路径先的jdbc.properties,修改ip地址为linux虚拟机的地址
- 运行项目
docker-compose up -d
- 在浏览器上访问localhost:5050/ssmgrogshop_war。登录名:sa 密码123(这时候可能会出现不能连接数据库的问题解决办法在第4部分)
2.3为上述环境添加nginx反向代理服务,实现负载均衡
- 创建default.conf
upstream tomcats { #轮询策略 server tomcat1:8080; server tomcat2:8080; } server { listen 7890; #nginx的监听端口 server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; proxy_pass http://tomcats; #访问nginx之后,会轮询访问代理的tomcat服务器 } }
- 修改docker-compose.yml
version: '2' services: tomcat1: #添加两个服务 image: tomcat:7 container_name: tomcat1 volumes: - "$PWD/webapps:/usr/local/tomcat/webapps" networks: webnet: ipv4_address: 15.22.0.15 tomcat2: image: tomcat:7 container_name: tomcat2 volumes: - "$PWD/webapps:/usr/local/tomcat/webapps" networks: webnet: ipv4_address: 15.22.0.16 #与第一个作区分 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: mynginx ports: - 7890:7890 volumes: - ./default.conf:/etc/nginx/conf.d/default.conf #挂载配置文件 depends_on: - tomcat1 - tomcat2 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 gateway: 15.22.0.2
- 文件树
- 访问localhost7890/ssmgrogshop_war验证是否配置成功
3.使用Docker搭建大数据集群环境
直接用机器搭建Hadoop集群,会因为不同机器配置等的差异,遇到各种各样的问题;也可以尝试用多个虚拟机搭建,但是这样对计算机的性能要求比较高,通常无法负载足够的节点数;使用Docker搭建Hadoop集群,将Hadoop集群运行在Docker容器中,使Hadoop开发者能够快速便捷地在本机搭建多节点的Hadoop集群
(备注,做这个实验的时候一定要将虚拟机的内存调大,否则运行实例的时候会卡死)
3.1 完成hadoop分布式集群环境配置,至少包含三个节点(一个master,两个slave)
- dockerfile
FROM ubuntu:18.04 ADD ./hadoopneed.zip /usr/local/hadoop/ COPY ./sources.list /etc/apt/sources.list MAINTAINER xuhongjian
- sources.list
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
- 文件树
docker build -t ubuntucs .
docker run -it --name ubuntucs ubuntucs
- 安装所需的程序
apt-get update apt-get install vim apt-get install ssh #登录服务器 apt-get install zip #解压工具
- 解压压缩包
cd /usr/local/hadoop/
unzip hadoopneed.zip
- 实现免密登录
/etc/init.d/ssh start vim ~/.bashrc //并在最后一行添加/etc/init.d/ssh start cd ~/.ssh/ ssh-keygen -t rsa //一直按回车直到结束 cat id_dsa.pub >> authorized_keys
- 配置环境变量
cd /usr/lib/ mkdir jvm cd jvm mv /usr/local/hadoop/hadoopneed/jdk1.8.0_162 jdk1.8.0_162 cd /usr/local mv ./hadoop/hadoopneed/hadoop-3.1.3 ./hadoop-3.1.3 vim ~/.bashrc
- 在文件头添加下列文字
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_162 export JRE_HOME=/JAVA_HOME/jre export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib export HADOOP_HOME=/usr/local/hadoop-3.1.3 export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin:$JAVA_HOME/bin
- 使环境变量生效并检验
source ~/.bashrc java -version hadoop version //注意这时候系统可能会提示权限不足,解决办法见问题解决部分
- 进入hadoop文件,可以看到下面这些文件
cd /usr/local/hadoop-3.1.3/etc/hadoop ls
- 配置文件修改
vim hadoop-env.sh //在末尾添加 export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_162/
- 继续修改其他配置文件
core-site.xml
在<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>
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> <property> <name>dfs.permissions.enabled</name> <value>false</value> </property> </configuration>
mapred-site.xml
<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
<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>
- 进入另一个目录继续配置4个文件(在文件头添加下面这些内容)
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
- 存档(防止丢失)
docker commit <容器id> ubuntu/hadoop //在另一个终端输入
exit
- 再打开两个终端,分别输入下列命令
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
- 打开IP地址文件,根据文件内容添加IP地址,下面是我的文件配置(每一个终端都要输入三个地址)
vim /etc/hosts
- 使用master登录其他节点,验证是否可以免密登录(登录完记得退出)
ssh slave01 //在master操作 ssh slave02 //......exit退出
- hadoop运行实例前的最后一步配置(在master节点上配置)
vim /usr/local/hadoop-3.1.3/etc/hadoop/workers //在master上做,将localhost修改为两个主机名即slave01 slave02 cd /usr/local/hadoop-3.1.3 bin/hdfs namenode -format //首次启动Hadoop需要格式化 sbin/start-all.sh //启动所有服务
- 使用jps命令查看各个节点的进程情况,如下图所示说明配置成功
3.2 运行hadoop 自带的测试实例。
- 准备测试样例的输入文件
bin/hdfs dfs -mkdir -p /user/hadoop/input bin/hdfs dfs -put ./etc/hadoop/*.xml /user/hadoop/input bin/hdfs dfs -ls /user/hadoop/input //可以看到九个文件
- 测试样例并输出结果
bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar grep /user/hadoop/input output 'dfs[a-z.]+' //运行的时候很慢,需要等待 bin/hdfs dfs -cat output/* //输出结果
4.出现的问题及解决方法
问题一:javaweb项目登录后不能连接数据库
解决方法:看报错是数据库出了问题,拒绝连接。我们查看一下mysql的运行日志
docker logs mymysql #最后一个参数是容器名
看到日志问题是处在权限不足上,那就修改权限,进到项目文件夹外(不能再文件夹内修改权限),我这边的javaweb项目是在一个叫lzz的文件夹内
chmod -R 777 lzz
停止容器
docker-compose down
删除mymysql镜像
docker rmi <镜像id>
重新运行
docker-compose up -d
问题二:打印java -version的时候提示权限不足
root@ebca236f904f:/usr/lib/jvm/jdk1.8.0_162/bin# java -version bash: /usr/lib/jvm/jdk1.8.0_162/bin/java: Permission denied
解决方法
若提示全向不够则输入命令chmod +x /usr/lib/jvm/jdk1.8.0_162/bin/java
为了避免以后出现更大的麻烦则将文件夹的权限全修改为777
chmod -R 777 /usr/local/hadoop-3.1.3
chmod -R 777 /usr/lib/jvm/jdk1.8.0_162/
5.作业所花的时间
实验用时:5小时
纠错用时:6小时
博客用时:2小时
总计:13小时