• 系统综合实践_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 !
          ':
                      count['tomcat1'] += 1
                elif response.text == 'This is tomcat2 !
          ':
                      count['tomcat2'] += 1
                elif response.text == 'This is tomcat3 !
          ':
                      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 <Container ID>
          
        • 执行测试程序,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
        <?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>
      
      • 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
      
      • 新开三个终端分别运行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相关等,收获还是很大。

  • 相关阅读:
    第十章学习笔记
    20201311陈子昂第十一章学习笔记
    第九章学习笔记
    第一次课堂笔记
    第七、八章学习笔记
    1.9. 触摸按钮(touch pad)测试
    1.8. 按钮
    访问修饰符 继承
    ie8下 子绝父相定位,鼠标滑入子元素增加宽高遮住父元素,导致子元素里面内容超出隐藏滑动时 字体滑动不一致的bug
    vscode打开自动显示cli.js
  • 原文地址:https://www.cnblogs.com/honger125/p/12895218.html
Copyright © 2020-2023  润新知