系统综合实践_4

1、Docker-compose实现Tomcat+Nginx负载均衡


  • nginx反向代理原理

    客户端向反向代理发送请求,接着反向代理转发请求至目标服务器,并把获得的内容返回给客户端。

  • nginx代理tomcat集群

    • 项目结构

    • docker-compose.yml

    version: "3.8"
    services:
    nginx:
    image: nginx
    container_name: t4-nginx
    ports:
    - 80:9191
    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

    • nginx配置文件default.conf

    upstream tomcats {
    server tct1:8080;
    server tct2:8081;
    server tct3:8082;
    }

    server {
    listen 9191;
    server_name localhost;

    location / {
    proxy_pass http://tomcats; # 请求转向tomcats
    }
    }

    • 执行docker-compose up

    • 浏览器访问localhost,显示的是自己编写的html

  • nginx负载均衡策略

    • 负载均衡策略
    • 轮询:最基本的配置方法,上面的例子就是轮询的方式,它是upstream模块默认的负载均衡默认策略。每个请求会按时间顺序逐一分配到不同的后端服务器。
    • weight:在轮询策略的基础上指定轮询的几率。
    • ip_hash:指定负载均衡器按照基于客户端IP的分配方式,这个方法确保了相同的客户端的请求一直发送到相同的服务器,以保证session会话。这样每个访客都固定访问一个后端服务器,可以解决session不能跨服务器的问题。
    • least_conn:把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。
    • 详见:Nginx服务器之负载均衡策略
    • 负载均衡测试

      • 轮询
      • 编写测试代码

        import requests

        url = "http://localhost"
        count = {'tomcat1':0,'tomcat2':0,'tomcat3':0}
        for i in range(0,100):
        response = requests.get(url)

        if response.text == 'This is tomcat1 !\n':
        count['tomcat1'] += 1
        elif response.text == 'This is tomcat2 !\n':
        count['tomcat2'] += 1
        elif response.text == 'This is tomcat3 !\n':
        count['tomcat3'] += 1
        print(response.text)

        print(count)

      • 测试结果

      • weight
      • 修改nginx配置文件default.conf

        upstream tomcats {
        server tct1:8080 weight=1;
        server tct2:8081 weight=2;
        server tct3:8082 weight=4;
        }

        server {
        listen 9191;
        server_name localhost;

        location / {
        proxy_pass http://tomcats; # 请求转向tomcats
        }
        }

      • 重启容器

        sudo docker restart

      • 执行测试程序,100次访问,访问数分别为14,29,57,比例接近1:2:4

      • ip-hash
      • 修改default.conf

        upstream tomcats {
        ip_hash
        server tct1:8080 weight=1;
        server tct2:8081 weight=2;
        server tct3:8082 weight=4;
        }

        server {
        listen 9191;
        server_name localhost;

        location / {
        proxy_pass http://tomcats; # 请求转向tomcats
        }
        }

      • 重启容器并执行测试程序,100次访问都访问同一服务器。

2、Docker-compose部署javaweb运行环境


  • 项目结构

  • docker-compose.yml

version: "3" #版 services: 务节点
tomcat: #tcat 服务
image: tcat #镜像
hostname: hostnam #容器的主机名
container_ne: tomcat00 #容器名
ports: #端口
- "5050:808
volumes: #数据卷
- /webapps:/usr/local/tomcat/webapps"
- ./wait-for-it.sh:/wt-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"
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;
}
}

  • 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
#复制gropshop.sql到/usr/local 
COPY grogshop.sql  /usr/local/
#把要执行的shell文件放到/docker-entrypoint-initdb.d/目录下,容器会自动执行这个shell
COPY docker-entrypoint.sh  $AUTO_RUN_DIR/
#给执行文件增加可执行权限
RUN chmod a+x $AUTO_RUN_DIR/docker-entrypoint.sh
# 设置容器启动时执行的命令
#CMD ["sh", "/docker-entrypoint-initdb.d/import.sh"

  • 修改端口容器

进入/webapps/ssmgrogshop_war/WEB-INF/classes/目录下的jdbc.properties文件,修改ip和端口。

  • 启动容器

docker-compose up -d

  • 浏览器访问http://127.0.0.1:8080/ssmgrogshop_war



3、Docker搭建大数据集群环境


    做的时候忘记截图了,到做完的时候才想起来,所以只截了后面部分内容的图片。

  • 实验环境

ubuntu 18.04
openjdk 1.8
hadoop 3.1.3

  • 创建并运行容器

docker run -it -v ~/:/root/build --name ubuntu ubuntu

  • 更新软件源 & 安装vim & 安装sshd

apt-get update
apt-get install vim # 用于修改配置文件
apt-get install ssh # 分布式hadoop通过ssh连接
/etc/init.d/ssh start # 开启sshd服务器
vim ~/.bashrc # 在文件末尾添加/etc/init.d/ssh start,实现ssd开机自启

  • 实现免密登陆

ssh-keygen -t rsa # 一直按回车即可
cd ~/.ssh
cat id_rsa.pub >> authorized_keys

  • 安装JDK

apt-get install openjdk-8-jdk

  • 安装hadoop

  • 将预先下载好的压缩包放到创建的目录下,以便后续安装

  • 将压缩包拷入容器

    cd /root/build
    tar -zxvf hadoop-3.1.3.tar.gz -C /usr/local #将hadoop压缩包放入本地build文件夹中
    cd /usr/local/hadoop-3.1.3
    ./bin/hadoop version # 验证安装

  • 配置hadoop集群

    • hadoop_env.sh:将export JAVA_HOME=${JAVA_HOME}替换成

    export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/

    • core-site.xml





    hadoop.tmp.dir
    file:/usr/local/hadoop-3.1.3/tmp
    Abase for other temporary directories.


    fs.defaultFS
    hdfs://master:9000

    • hdfs-site.xml





    dfs.replication
    1


    dfs.namenode.name.dir
    file:/usr/local/hadoop-3.1.3/tmp/dfs/name


    dfs.datanode.data.dir
    file:/usr/local/hadoop-3.1.3/tmp/dfs/data


    dfs.permissions.enabled
    false

    • mapred-site.xml





    mapreduce.framework.name
    yarn


    yarn.app.mapreduce.am.env
    HADOOP_MAPRED_HOME=/usr/local/hadoop-3.1.3


    mapreduce.map.env
    HADOOP_MAPRED_HOME=/usr/local/hadoop-3.1.3


    mapreduce.reduce.env
    HADOOP_MAPRED_HOME=/usr/local/hadoop-3.1.3

    • yarn-site.xml





    yarn.nodemanager.aux-services
    mapreduce_shuffle


    yarn.resourcemanager.hostname
    Master


    yarn.nodemanager.vmem-pmem-ratio
    2.5

    • 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 ubuntu_hadoop

    • 新开三个终端分别运行ubuntu_hadoop镜像,表示Hadoop集群中的master,slave01和slave02

    第一个终端

    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

    • 配置master,slave01和slave02的地址信息

        分别打开/etc/hosts可以查看本机的ip和主机名信息,得到三个ip和主机地址信息,把三个地址信息分别复制到master,slave01和slave02的/etc/hosts

    • 检测master是否可以连接slave01和slave02

    ssh slave01
    ssh slave02


    • 修改master上的workers文件

        将localhost修改为slave01 slave02

    • 启动服务

    cd /usr/local/hadoop-3.1.3
    bin/hdfs namenode -format # 格式化文件系统
    sbin/start-dfs.sh # 开启NameNode和DataNode服务
    sbin/start-yarn.sh

    • 使用jps查看三个终端



  • 运行测试实例

    • grep

    hdfs dfs -mkdir -p /user/root/input
    hdfs dfs -put /usr/local/hadoop-3.1.3/etc/hadoop/s-site.xml input
    hadoop jar /usr/local/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar grep input output 'dfs[a-z.]+'
    hdfs dfs -cat output/

    • wordcount

    hdfs dfs -mkdir -p /user/root/input
    vim txt1.txt
    vim txt2.txt
    hdfs dfs -put ./.txt input
    hadoop jar /usr/local/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount input output1
    hdfs dfs -cat output1/

4、问题 & 解决

  • 在负载均衡测试时,编写了python代码,却不知道如何在终端上运行,因此顺便研究了一下如何在linux系统的终端上运行py文件,只需要输入python3 /<File Path>/XX.py即可。

  • 在部署Javaweb时不能正确访问web,后来经同学指点发现是web没有连接到数据库,而是连接到了tomcat,修改后重新运行即可。

5、总结


    这次试验整整花了我两个下午+一个晚上,大部分时间都是花在了实验二和三,幸亏实验三的步骤和大数据实验有很多相似的地方,自己在才能少走了许多弯路。通过这次实验,也学了很多内容,包括反向代理、负载均衡策略、javaweb的简单部署、hadoop相关等,收获还是很大。

posted @ 2020-05-16 18:02  Mys_02  阅读(241)  评论(0)    收藏  举报