• 2020系统综合实践 第4次实践作业


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

    概念

    正向代理:客户端想要访问一个服务器,但是它可能无法直接访问这台服务器,这时候这可找一台可以访问目标服务器的另外一台服务器,而这台服务器就被当做是代理人的角色 ,称之为代理服务器,于是客户端把请求发给代理服务器,由代理服务器获得目标服务器的数据并返回给客户端。客户端是清楚目标服务器的地址的,而目标服务器是不清楚来自客户端,它只知道来自哪个代理服务器,所以正向代理可以屏蔽或隐藏客户端的信息。
    反向代理:从上面的正向代理,你会大概知道代理服务器是为客户端作代理人,它是站在客户端这边的。其实反向代理就是代理服务器为服务器作代理人,站在服务器这边,它就是对外屏蔽了服务器的信息,常用的场景就是多台服务器分布式部署,像一些大的网站,由于访问人数很多,就需要多台服务器来解决人数多的问题,这时这些服务器就由一个反向代理服务器来代理,客户端发来请求,先由反向代理服务器,然后按一定的规则分发到明确的服务器,而客户端不知道是哪台服务器。常常用nginx来作反向代理。
    Nginx的负载均衡:
    负载:就是Nginx接受请求

    均衡:Nginx将收到的请求按照一定的规则分发到不同的服务器进行处理

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

    创建项目的目录结构如下:

    即代理三个tomcat

    编写nginx的默认配置文件

    通过upstream tomcats配置后面负载均衡的策略选择
    先使用的是轮询算法(默认),配置内容如下

    upstream tomcats {
        server c_tc1:8080; 
        server c_tc2:8080; 
        server c_tc3:8080; 
    }
    
    server {
        listen 2419;
        server_name localhost;
    
        location / {
            proxy_pass http://tomcats; # 请求转向tomcats
        }
    }
    

    docker-compose.yml

    version: "3.8"
    services:
        nginx:
            image: nginx
            container_name: c_ngx
            ports:
                - 80:2419
            volumes:
                - ./nginx/default.conf:/etc/nginx/conf.d/default.conf # 挂载配置文件
            depends_on:
                - tomcat01
                - tomcat02
                - tomcat03
    
        tomcat01:
            image: tomcat
            container_name: c_tc1
            volumes:
                - ./tomcat01:/usr/local/tomcat/webapps/ROOT # 挂载web目录
    
        tomcat02:
            image: tomcat
            container_name: c_tc2
            volumes:
                - ./tomcat02:/usr/local/tomcat/webapps/ROOT
    
        tomcat03:
            image: tomcat
            container_name: c_tc3
            volumes:
                - ./tomcat03:/usr/local/tomcat/webapps/ROOT
    

    index.html

    I am the host 03/02/01
    

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

    常用的负载均衡策略有

    • 轮询(默认)
    • 指定权重
    • IP绑定 ip_hash
    • fair(第三方)
    • url_hash(第三方)

    这里选择测试默认的轮询算法和指定权重算法

    轮询算法

    nginx的配置文件上面已经给出

    cd homework4/
    sudo docker-compose up -d --build
    

    成功运行yml文件,由于之前已经创建完成,结果如下

    于是可以通过浏览器访问localhost发现是可以成功访问之前设置的index.html界面的,并且刷新界面结果会轮询。这里为了直观看出负载均衡的策略,直接用创建py文件测试

    test_lx.py
    import requests
    url = 'http://localhost'
    for i in range(1,10):
        response=requests.get(url)
        print(response.text)
    

    得到结果如下,可发现是三个tomcat服务器是轮流执行的

    权重算法

    更改default.conf文件

    upstream tomcats {
        server c_tc1:8080 weight=1;   //weight后面的数字表示权重
        server c_tc2:8080 weight=3;
        server c_tc3:8080 weight=5;
    }
    
    server {
        listen 2419;
        server_name localhost;
    
        location / {
            proxy_pass http://tomcats; # 请求转向tomcats
        }
    }
    

    重新sudo docker-compose up -d --build
    直接使用py代码测试

    test.qz.py
    import requests
    url = 'http://localhost'
    count={'I am the host 03':0,'I am the host 01':0,'I am the host 02':0}
    for i in range(0,90):
        response=requests.get(url)
        if  'I am the host 03' in response.text:
            count['I am the host 03'] += 1
        if  'I am the host 02' in response.text:
            count['I am the host 02'] += 1
        if  'I am the host 01' in response.text:
            count['I am the host 01'] += 1
        print(response.text)
    print(count)
    

    显然三种结果的出现比例和权重是一致的

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

    • 分别构建tomcat、数据库等镜像服务;
    • 成功部署Javaweb程序,包含简单的数据库操作;
    • 为上述环境添加nginx反向代理服务,实现负载均衡。
      创建项目文件,文件结构如图(javaweb程序老师给的参考博客)


      其中war包放在webapp文件目录下

    文件配置

    docker-compose.yml

    version: "3"   
    services:    
      tomcat00:     
        image: tomcat    
        hostname: hostname       
        container_name: tomcat00   
        ports:      
         - "5050:8080"          #后面访问网页的时候要选择对应的端口号5050
        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" 
    
        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 tomcats {
        server tomcat00:5050; 
    
    }
    
    server {
        listen 8080
        server_name localhost;
    
        location / {
            proxy_pass http://tomcat123;
            proxy_set_header   Host    $host; 
            proxy_set_header   X-Real-IP   $remote_addr; 
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    
        }
    }
    
    
    

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

    修改连接数据库的IP

    通过ip config -a查看本机ip地址,inet对应的即为结果

    修改jdbc.properties对应的ip地址和之前设置的对应端口号

    启动容器

    docker-compose up -d --build
    

    数据库操作

    访问网页,登陆

    http://127.0.0.1:5050/ssmgrogshop_war
    

    对应的可以进行数据库操作

    修改nginx配置文件,反向代理tomcat

    upstream tomcats {
        server tomcat00:5050; 
        server tomcat00:5051; 
        server tomcat00:5052; 
         
    }
    
    

    修改yml文件,增加

    tomcat01:     
        image: tomcat    
        hostname: hostname       
        container_name: tomcat01   
        ports:      
         - "5051:8080"          #后面访问网页的时候要选择对应的端口号5050
        volumes:  #数据卷
         - "./webapps:/usr/local/tomcat/webapps"
         - ./wait-for-it.sh:/wait-for-it.sh
        networks:   #网络设置静态IP
          webnet:
            ipv4_address: 15.22.0.16
      tomcat02:     
        image: tomcat    
        hostname: hostname       
        container_name: tomcat02   
        ports:      
         - "5052:8080"          #后面访问网页的时候要选择对应的端口号5050
        volumes:  #数据卷
         - "./webapps:/usr/local/tomcat/webapps"
         - ./wait-for-it.sh:/wait-for-it.sh
        networks:   #网络设置静态IP
          webnet:
            ipv4_address: 15.22.0.17
      nginx:
        depends_on:
         - tomcat00
         - tomcat01
         - tomcat02   
    

    重新运行容器,可以发现在三个端口下都可以访问nginx

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

    环境搭建

    • 拉取ubantu镜像
    sudo su
    docker pull ubantu
    
    • 创建dockerfile文件
    FROM ubuntu
    maintainer Yaobink
    
    • 进入ubantu容器
    docker build -t ubuntu .
    docker run -it --name ubuntu ubuntu
    

    Ubuntu系统初始化

    • 更新系统软件源
      更新系统源命令如下:
    apt-get update
    
    • 安装vim
    apt-get install vim
    
    • 安装sshd
      接着安装sshd,因为在开启分布式Hadoop时,需要用到ssh连接slave:
    apt-get install ssh
    

    然后运行如下脚本即可开启sshd服务器:

    /etc/init.d/ssh start
    

    但是这样的话,就需要每次在开启镜像时,都需要手动开启sshd服务,因此我们把这启动命令写进~/.bashrc文件,这样我们每次登录Ubuntu系统时,都能自动启动sshd服务;

    vim ~/.bashrc
    

    在该文件中最后一行添加如下内容:

    /etc/init.d/ssh start
    

    配置sshd
    安装好sshd之后,我们需要配置ssh无密码连接本地sshd服务,如下命令:

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

    执行完上述命令之后,即可无密码访问本地sshd服务;

    安装JDK

    • 根据官方文档,最好下载java8
    apt install openjdk-8-jdk
    
    • 安装好后需要配置环境变量
    vim ~/.bashrc  #打开配置文件
    #在最后添加使~/.bashrc生效
    export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
    export PATH=$PATH:$JAVA_HOME/bin
    source ~/.bashrc  
    

    存档

    docker commit 09ab62943c02  ubuntu/jdk8 
    docker run -it -v /home/y/hw4_3/build:/root/build --name ubuntu-jdk8 ubuntu/jdk8
    

    安装Hadoop

    首先下载好Hadoop,这里下载的是3.2.1的版本,移入ubuntu桌面
    然后通过cp复制到挂载的文件目录下,解压文件,并验证安装

    sudo cp /home/y/桌面/hadoop-3.2.1.tar.gz /home/y/hw4_3/build
    tar -zxvf hadoop-3.2.1.tar.gz -C /usr/local
    cd /usr/local/hadoop-3.2.1
    ./bin/hadoop version
    

    配置Hadoop集群

    • 进入配置文件存放目录:
    cd /usr/local/hadoop-3.2.1/etc/hadoop
    
    • 修改环境变量
    vim hadoop-env.sh
    export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ 
    
    • 修改core-site.xml
    vim core-site.xml
    

    添加:

    <configuration>
          <property>
              <name>hadoop.tmp.dir</name>
              <value>file:/usr/local/hadoop/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
    vim hdfs-site.xml
    

    添加:

    <configuration>
        <property>
            <name>dfs.namenode.name.dir</name>
            <value>file:/usr/local/hadoop/namenode_dir</value>
        </property>
        <property>
            <name>dfs.datanode.data.dir</name>
            <value>file:/usr/local/hadoop/datanode_dir</value>
        </property>
        <property>
            <name>dfs.replication</name>
            <value>3</value>
        </property>
    </configuration>
    
    • 修改mapred-site.xml
    vim 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.2.1</value>
        </property>
        <property>
            <name>mapreduce.map.env</name>
            <value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.2.1</value>
        </property>
        <property>
            <name>mapreduce.reduce.env</name>
            <value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.2.1</value>
        </property>
    </configuration>
    
    • 修改yarn-site.xml
    vim yarn-site.xml
    

    添加:

    <configuration>
        <property>
            <name>yarn.nodemanager.aux-services</name>
            <value>mapreduce_shuffle</value>
        </property>
        <property>
            <name>yarn.resourcemanager.hostname</name>
            <value>master</value>
        </property>
    </configuration>
    

    修改脚本

    • 进入脚本文件存放目录:
    cd /usr/local/hadoop-3.2.1/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
    
    • 存档
    sudo docker commit ID ubuntu/hadoop
    

    运行Hadoop集群

    • 在三个终端上开启三个容器运行ubuntu/hadoop镜像,分别表示Hadoop集群中的master,slave01和slave02;
    # 第一个终端
    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
    
    • 修改/etc/hosts
    vim /etc/hosts
    #修改为
    172.17.0.2      master
    172.17.0.3      slave01
    172.17.0.4      slave02
    

    • 测试ssh
      检测下是否master是否可以连上slave01和slave02(exit为退出)
    ssh slave01
    ssh slave02
    

    • 修改workers
    vim /usr/local/hadoop-3.2.1/etc/hadoop/workers
    # 将localhost替换成两个slave的主机名
    slave01
    slave02
    

    启动集群

    在master终端上运行如下命令

    cd /usr/local/hadoop-3.2.1
    bin/hdfs namenode -format # 格式化文件系统
    sbin/start-dfs.sh # 开启NameNode和DataNode服务
    bin/hdfs dfs -mkdir /user # 建立HDFS文件夹,也可以放到下面示例程序中进行
    bin/hdfs dfs -mkdir /user/root
    bin/hdfs dfs -mkdir input
    bin/hdfs dfs -put etc/hadoop/*.xml input # 将xml复制到input下,作为示例程序输入
    sbin/start-yarn.sh # 开启ResourceManager和NodeManager服务
    jps # 查看服务状态
    

    运行Hadoop示例程序

    在master终端运行:

    bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.1.jar grep input output 'dfs[a-z.]+' # 运行示例
    bin/hdfs dfs -get output output # 获取输出结果
    cat output/* # 查看输出结果
    sbin/stop-all.sh # 停止所有服务
    

    查看文件列表

    在hdfs上的output目录下查看到运行结果:

    ./bin/hdfs dfs -cat output/*
    

    得到的结果为

    问题:

    (1)
    在配置ssh无密码连接本地sshd服务的时候出现了找不到目录的情况

    后面查资料知道这个并不用先进入文件夹,而是可以直接执行自动创建这个目录

    接着要先cd进入目录在执行cat id_rsa.pub >> authorized_keys,否则同样会找不到目标文件
    (2)在运行Hadoop示例程序的时候ubuntu卡住了,所以我又重新创建了三个运行容器重新实验,然后在过程中发现,workers这个文件的修改应该得在master的目录下,否则后面在jps查看服务状态的过程种会出现错误,在slave01/02的jps命令下只能看到56Jps这样的情况,而NodeManager和DataNode都不存在。

    用时

    大概花了两个下午加一个晚上的时间,主要还是花在了第三个实验和第二个实验的javaweb的文件阅读上,最后无奈还是剽一下范例文档的war包。
    感觉好多内容都是需要学习的,这种混杂的东西如果有一点不通就经常容易出现错误,就比如第三个实验有的时候某个步骤做错了就得重新开始,感觉特别麻烦,虽然前面有一些存档,不过毕竟还是有一些是无法保存的,但是万幸存档重来其实也节省了许多时间。

  • 相关阅读:
    火币Huobi API Websocket
    火币Huobi API
    OKEX API(Websocket)
    OKEX API
    Linux下Miniconda量化环境安装
    Numba:高性能Python编译器
    十进制和十六进制互相转换
    JavaScript 原型和原型链
    Redux 进阶之 react-redux 和 redux-thunk 的应用
    Vue 中 $nextTick() 的应用
  • 原文地址:https://www.cnblogs.com/yaobink/p/12882336.html
Copyright © 2020-2023  润新知