• 第4次实践作业


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

    1.理解nginx反向代理原理;

      举例一下,目前如日中天的某宝网站,每天同时连接到网站的访问人数已经爆表,单个服务器远远不能满足人民日益增长的购买欲望了,此时就出现了一个大家耳熟能详的名词:分布式部署;也就是通过部署多台服务器来解决访问人数限制的问题;某宝网站中大部分功能也是直接使用nginx进行反向代理实现的,并且通过封装nginx和其他的组件之后起了个高大上的名字:Tengine,那么反向代理具体是通过什么样的方式实现的分布式的集群操作呢,我们先看一个示意图:

      通过上述的图解大家就可以看清楚了,多个客户端给服务器发送的请求,nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。此时~请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,nginx扮演的就是一个反向代理角色。简而言之,反向代理就是主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息。

    项目场景

      通常情况下,我们在实际项目操作时,正向代理和反向代理很有可能会存在在一个应用场景中,正向代理代理客户端的请求去访问目标服务器,目标服务器是一个反向单利服务器,反向代理了多台真实的业务处理服务器。具体的拓扑图如下:

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

    2.1项目分支如下:

    文档如下:

    docker-compose.yml

    default.conf

    index.html
    三个文件夹里头内容为tomcat1、tomcat2、tomcat3

    2.2运行yml文件

    2.3访问浏览器localhost

    刷新后轮番出现以下界面:



    神奇!

    2.4查看新创建的容器状态

    3.了解nginx的负载均衡策略,并至少实现nginx的2种负载均衡策略;

    3.1轮询方式

    3.1.1新建临时文档temp.py用于测试

    temp.py

    import requests
    
    url="http://localhost"
    
    for i in range(0,10):
    	reponse=requests.get(url)
    	print(reponse.text)
    

    测试

    3.2权重方式

    3.2.1修改default.conf文档用于测试

    upstream tomcats {
        server ex4_tomcat01:8080 weight=1; #weight参数用于指定轮询几率,weight的数值与访问比率成正比
        server ex4_tomcat02:8080 weight=1; #设置比重为1:1:8
        server ex4_tomcat03:8080 weight=8; 
    }
    

    3.2.2重启nginx容器

    3.2.3新建临时文档temp1.py用于测试

    import requests
    url='http://localhost'
    count={}
    for i in range(0,100):
        response=requests.get(url)
        if response.text in count:
            count[response.text]+=1;
        else:
            count[response.text]=1
    print(count)
    

    测试

    3.3基于客户端IP的分配方式

    • weight 权重过大代表承担的负载就越大
    • max_fails 失败超过指定次数会暂停或请求转往其它服务器
    • fail_timeout 失败超过指定次数后暂停时间
    • 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题

    3.3.1修改default.conf文档

    upstream tomcats {
        ip_hash;    #保证每个访客固定访问一个后端服务器
        server ex4_tomcat1:8080 weight=3; 
        server ex4_tomcat2:8080; 
        server ex4_tomcat3:8080 max_fails=3 fail_timeout=20s; 
    }
    

    通过temp1.py测试(记得要重启容器

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

    参考博客:使用docker-compose部署Javaweb项目

    1.建立文件结构


    default.conf

    upstream tomcats {           
    
        server tomcat01:8080;
    
        server tomcat02:8080;
    
    }
    
    
    
    server {
    
        listen       2020;    
    
        server_name  localhost;
    
    
    
        location / {
    
            root   /usr/share/nginx/html;
    
            index  index.html index.htm;
    
    	proxy_pass http://tomcats;     
    
        }
    

    docker-compose

    version: "3"   #版本
    services:     #服务节点
      tomcat01:     #tomcat 服务
        image: tomcat    #镜像
        hostname: hostname       #容器的主机名
        container_name: tomcat01   #容器名
        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
      tomcat02:     #tomcat 服务
        image: tomcat    #镜像
        hostname: hostname       #容器的主机名
        container_name: tomcat02   #容器名
        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   #子网
    

    docker-entrypoint.sh

    #!/bin/bash
    mysql -uroot -p123456 << EOF   
    source /usr/local/grogshop.sql;
    

    Dockerfile

    #  这个是构建MySQL的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"]
    

    2.部署Javaweb程序

    2.1修改连接数据库的IP

    vim ~/ex4_2/webapps/ssmgrogshop_war/WEB-INF/classes/jdbc.properties
    

    2.2启动容器

    docker-compose up -d
    

    2.3浏览器访问前端页面

    实现负载均衡

    http://10.0.2.15:5050/ssmgrogshop_war
    

    http://10.0.2.15:5050/ssmgrogshop_war
    

    2.3数据库操作


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

    直接用机器搭建Hadoop集群,会因为不同机器配置等的差异,遇到各种各样的问题;也可以尝试用多个虚拟机搭建,但是这样对计算机的性能要求比较高,通常无法负载足够的节点数;使用Docker搭建Hadoop集群,将Hadoop集群运行在Docker容器中,使Hadoop开发者能够快速便捷地在本机搭建多节点的Hadoop集群。

    1.初始化系统

    1.1在Docker安装Ubuntu系统

    docker pull ubuntu
    

    个人文件下创建一个目录并运行Ubuntu系统

    cd ~
    mkdir build
    

    1.2Ubuntu系统初始化

    更新系统软件源
    16.04系统所需的源(这里使用的是阿里源)

    apt-get update
    
    

    安装vim、sshd

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

    细节忽略
    配置sshd

    ssh-keygen -t rsa #一直按回车键即可
    cat id_dsa.pub >> authorized_keys
    

    至此实现免密验证

    1.3安装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生效
    

    保存镜像文件

    docker ps
    docker commit 91f51e3bb091 ubuntu/jdk8
    

    2.Hadoop安装与配置

    2.1安装Hadoop

    开启保存的那份镜像ubuntu/jdk8

    sudo docker commit 容器id ubuntu/jdk8      #jkd8版本的ubuntu
    sudo docker run -it -v /home/caifeng/build:/root/build --name ubuntu-jdk8 ubuntu:jdk8#这一步一定别漏,我漏了,后面会出问题
    

    安装并验证Hadoop

    docker cp ./build/hadoop-3.1.3.tar.gz 容器ID:/root/build
    cd /root/build
    tar -zxvf hadoop-3.1.3.tar.gz -C /usr/local
    vim ~/.bashrc  #添加以下三行
    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生效
    hadoop version
    

    2.2配置Hadoop

    进入配置目录

    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

    <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

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

    进入脚本目录

    cd /usr/local/hadoop-3.1.3/sbin
    

    对于start-dfs.shstop-dfs.sh文件,添加下列参数

    HDFS_DATANODE_USER=root
    HADOOP_SECURE_DN_USER=hdfs
    HDFS_NAMENODE_USER=root
    HDFS_SECONDARYNAMENODE_USER=root
    

    对于start-yarn.shstop-yarn.sh,添加下列参数

    YARN_RESOURCEMANAGER_USER=root
    HADOOP_SECURE_DN_USER=yarn
    YARN_NODEMANAGER_USER=root
    

    2.2保存镜像

    另开一个终端运行以下指令:

    docker commit 容器ID ubuntu/hadoop
    

    2.3另开三个终端运行主机

    # 第一个终端
    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
    

    运行vim /etc/hosts,根据各自ip修改为如下形式

    172.17.0.4      master
    172.17.0.5      slave01
    172.17.0.6      slave02
    

    2.4在master终端做结点测试

    从master连接到slave各个结点

    ssh slave01
    ssh slave02
    exit 
    

    2.5在master主机上修改workers

    vim /usr/local/hadoop-3.1.3/etc/hadoop/workers
    

    将默认的localhost替换为

    slave01
    slave02
    

    3.测试Hadoop并运行程序实例

    3.1测试Hadoop集群

    打开master终端

    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)遇到的问题及解决方案

    1.Ubuntu 16.04安全重启后处于emergency mode状态无法进入图形界面问题

    • 登陆root,输入用户名和密码
    • vim /etc/fstab ,检查磁盘挂载信息
    • 注释掉自己增加的内容,如果确定不在使用可以删除
    • 重启ok
      待续

    (5)小结

      这次实验的量真的太大了,我大概边写博客边做花了30多个小时。真的这次实践有太多感想了。
      前两个实验还好,了解了nginx的负载均衡策略,其实还挺有意思的,轮询和权重都不失为一种好方法,在nginx部署项目的时候运用一下负载均衡也是极佳的选择,这是真实能够给之后的项目提供帮助的负载均衡,至于基于客户端IP的分配方式其实挺神奇的,我至今还是对他怀着惊叹的态度。然后就是第三次实验了,第三次是使用Docker搭建大数据集群环境。不得不说第三个实验的容错率太低了,我硬生生错了6次,基本上都是从头来过,尤其到最后一次直接系统崩溃了,安全重启后又进入了emergency mode..我检查了一波磁盘挂载信息,然后发现是之前有加入了一些东西,注释过后才总算可以启动,我感觉我在玩火,至此之后我的虚拟机ubantu系统启动都需要很长的时间。
      但是总体来说,还是学会了许多东西,最后看到结果正确的时候异常兴奋,这次实践也算是在坑底做了一次跳跳蛙。

  • 相关阅读:
    bug_ _ 常见的bug1
    键盘-App监听软键盘按键的三种方式
    listview--记录ListView滚动停止位置与设置显示位置
    android shape的使用
    转-android图片降低图片大小保持图片清晰的方法
    转-Android SHA1与Package获取方式
    Android listview中使用checkbox
    保存恢复临时信-Android 中使用onSaveInstanceState和onRestoreInstanceState
    转-Android客户端和服务端如何使用Token和Session
    转-Activity中使用orientation属性讲解及需注意的问题
  • 原文地址:https://www.cnblogs.com/TITIN24/p/12901107.html
Copyright © 2020-2023  润新知