• 2020系统综合实验期末大作业 第20组


    选题简介

    我们小组这次大作业的主题是对目前疫情情况作出分析和展示,让用户能时刻掌握知晓目前疫情的发展情况。通过web访问页面可以了解到全国各地的疫情状况,包括现有确诊人数、累计确诊、累计治愈和累计死亡人数,以及各项较昨日的新增人数等。我们的web项目是基于docker以微服务完成项目部署。

    项目设计

    我们的web项目包括前端、后端和数据库三个部分

    前端部分

    前端页面通过vue来快速搭建,使用element-ui和echarts来搭建视图
    项目代码详见GitHub仓库

    微服务部署

    • 获取nginx镜像
    sudo docker pull nginx
    
    • 在项目根目录下创建nginx文件夹,并将前端build后得到的dist文件夹放到nginx文件夹下
      img
    • 创建default.conf文件
    server {
        listen       80;
        server_name  localhost;
    
        #charset koi8-r;
        access_log  /var/log/nginx/host.access.log  main;
        error_log  /var/log/nginx/error.log  error;
    
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }
    
        #error_page  404              /404.html;
    
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
    
    • 创建Dockerfile文件
    FROM nginx  #基础镜像
    COPY dist/ /usr/share/nginx/html/ #添加文件
    COPY default.conf /etc/nginx/conf.d/default.conf
    
    • 基于该dockerfile构建vue应用镜像
    sudo docker build -t vuenginxcontainer .
    

    img

    • 基于vuenginxcontainer镜像启动容器,运行命令如下:
    sudo docker run -p 3000:80 -d --name vueApp vuenginxcontainer
    

    img

    • 此时前端在docker已经部署完成,构建镜像已上传到dockerhub 前端镜像
    sudo docker commit -m 'add vueApp' vuenginxcontainer jamwongh/vuenginx
    sudo docker login && docker push jamwongh/vuenginx
    

    img

    • 还未部署后端的前端页面访问
      img

    后端部分

    项目代码详见GitHub仓库

    微服务部署

    • 创建Dockerfile文件
    #依赖镜像名称和ID
    FROM jdk8
    #指定镜像创建者信息
    MAINTAINER zxl
    #添加文件
    COPY infectsystem.jar /app.jar 
    CMD java -jar /app.jar
    EXPOSE 8080 #暴露端口
    
    • 构建自定义镜像
    sudo docker build -t infect .
    
    • 运行后端容器
    sudo docker run -d --name project -p 8080:8080 infect
    
    • 构建镜像已上传到dockerhub
    sudo docker commit infect zxl2464331339/infect:project-lastest2
    sudo docker login && docker push zxl2464331339/infect:project-lastest2
    

    数据库部分

    相关代码

    -- Host: localhost    Database: covid           /*创建数据库covid*/
    /*创建表data*/
    DROP TABLE IF EXISTS `data`;
    CREATE TABLE `data` (
      `provinceName` text,
      `cure` bigint DEFAULT NULL,
      `date` text,
      `dead` bigint DEFAULT NULL,
      `doubt` text,
      `infect` bigint DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
    DROP TABLE IF EXISTS `province`;
    /*创建表province*/
    CREATE TABLE `province` (
      `provinceName` text
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
    

    微服务部署

    • pull mysql基础镜像
    sudo docker pull mysql
    
    • Dockerfile文件
    FROM mysql #基础镜像
    MAINTAINER zxl
    mysql -e "grant all privileges on *.* to 'root'@'%' identified by '123456';" &&
    mysql -e "grant all privileges on *.* to 'root'@'localhost' identified by '123456';"      #root在本地,非本地登录时都使用123456密码
    EXPOSE 3306 #暴露端口
    
    • 构建镜像
    sudo docker build mysql2 .
    
    • 运行mysql容器
    sudo docker run -d --name mysql2 -p 3306:3306 mysql2
    
    • 保存镜像
    sudo docker commit mysql2 zxl2464331339/infect:mysql-v2
    
    sudo docker login &&docker push zxl2464331339/infect:mysql-v2
    

    爬取数据

    相关代码

    def resolve_info(data, tag):
        """
        解析数据
        @param data:
        @param tag:
        @return:
        """
        if tag == 'province':
            # 城市
            data_name =  [string for string in data.find('p', class_='subBlock1___3cWXy').strings][0]
            return [data_name]
        else:
            # 省份
            data_name = [string for string in data.find('p', class_='subBlock1___3cWXy').strings][0]
                # 累计确诊人数
            data_sum_diagnose = data.find('p', class_='subBlock3___3dTLM').string
                # 死亡人数
            data_death = data.find('p', class_='subBlock4___3SAto').string
    
                # 治愈人数
            data_cure = data.find('p', class_='subBlock5___33XVW').string
            data_time = datetime.now() + timedelta(-1)
            data_time_str = data_time.strftime('%Y-%m-%d')
            data_cure=int(data_cure.replace(',',''))
            data_sum_diagnose=int(data_sum_diagnose.replace(',','')) #数据去除千分符
            data_death=int(data_death.replace(',',''))
            data_doubt=None
            return [data_name, data_cure,data_time_str, data_death,data_doubt,data_sum_diagnose]
        # 设置昨天的日期作为数据日期
    
    if __name__ == '__main__':
            
            print("capturing data……")
            url = 'https://ncov.dxy.cn/ncovh5/view/pneumonia'
            executable_path = "D:chromedriverchromedriver.exe"
                # 设置不弹窗显示
            chrome_options = Options()
            chrome_options.add_argument('--headless')
            chrome_options.add_argument('--disable-gpu')
            browser = webdriver.Chrome(options=chrome_options, executable_path=executable_path)
                # 弹窗显示
                # browser = webdriver.Chrome(executable_path=executable_path)
            wait = ui.WebDriverWait(browser, 10)
            browser.get(url)
            for x in browser.find_elements_by_class_name('expandRow___1Y0WD'):
                link = webdriver.ActionChains(browser).move_to_element(x).click(x).perform()
              # 输出网页源码
            content = browser.page_source
            soup = BeautifulSoup(content, 'html.parser')
            soup_province_class = soup.find('div', class_='areaBox___Sl7gp themeA___1BO7o numFormat___nZ7U7 flexLayout___1pYge').find_all('div', class_='areaBlock1___3qjL7')
    
            list_province_data = []
            list_province=[]
            for per_province in soup_province_class:
                    # 如果存在img标签,则认为该数据有效,进行解析。(否则该数据应该是表头,应跳过)
                    if per_province.find_all('p')[0].find('img'):
                            # 省份数据
                            list_current_province = resolve_info(per_province, 'data')
                            province=resolve_info(per_province,'province')
                            list_province_data.append(list_current_province)
                            list_province.append(province)
            # 数据转换成 DataFrame
            df_province_data = pd.DataFrame(list_province_data,
                                            columns=['provinceName', 'cure', 'date', 'dead', 'doubt','infect'])
            df_province=pd.DataFrame(list_province,columns=['provinceName'])
            browser.quit()
            print("capture completed")
            print("inserting data into mysql……")
    
            save_to_mysql(df_province_data,'data')
            print("insert completed!")
    

    运行结果

    img

    三个部分的容器连接

    采用docker compose来进行容器连接

    • 将三个镜像全部pull下来
    sudo docker pull jamwongh/vuenginx
    sudo docker pull zxl2464331339/infect:project-latest2
    sudo docker pull zxl2464331339/infect:mysql-v2
    
    • 文件准备
      img
    • 创建compose.yml文件
    version: "3"
    services:
     appvue:
        image: jamwongh/vuenginx:latest                #指定镜像名
        container_name: appvue             #指定容器名
        ports:
          - "3000:80"                       #修改端口映射
        depends_on:
          - mysql2
    
    
     project:
        image: zxl2464331339/infect:project-lastest2 
        container_name: project 
        depends_on:
          - appvue
          - mysql2
        ports:
          - "8080:8080"
    
     mysql2:
       image: zxl2464331339/infect:mysql-v2
       container_name: mysql2
       ports:
         - "3306:3306"
       volumes:
         - ./mysql:/var/lib/mysql       #挂载容器卷,实现数据同步,防止数据丢失
    
    • 执行docker-compose文件
    sudo docker-compose up -d
    

    img

    • 查看三个容器是否正常运行
      img
    • 进入mysql2容器
    sudo docker exec -it [容器ID] /bin/bash   #进入容器
    mysql -u root -p     #登录mysql
    create database COVID;       #创建数据库
    use COVID;
    set names utf8;
    source COVID.sql;
    

    运行结果

    • 先进行后端页面测试
      img
    • 前端页面测试
      img
    • 数据库展示
      img

    组内分工+贡献比

    学号 姓名 分工 贡献比
    031702337 叶琦熠 爬虫,后端与前端代码改进 20%
    031702316 翟鑫亮 后端与数据库微服务部署 20%
    031702525 周鑫煌 前端微服务部署 20%
    031702301 王瑞卿 容器连接 15%
    031702312 鲍冰如 容器连接 15%
    031702313 周丽榕 数据库设计,撰写博客 10%

    总结

    叶琦熠:通过本次的大作业,我熟练了之前学习过的一些爬虫知识并予以实践,以及学习了前端vue与后端代码接口的实现,巩固了之前所学习的微服务部署相关知识……通过这次的大作业,作为组长(虽然是老师默认指定的),我逐渐地学会如何与队员沟通以及做好队员与队员之间的分工协调工作,虽然还是有地方考虑的不周到,但还是得到了队员的包容与理解,团队氛围还算融洽,我也是得到了些成长吧。

    鲍冰如:这次实验主要是运用此前学习到的微服务知识,将团队项目部署到微服务,对前后端以及数据库的连接有了更深的了解,遇到问题会和队友一起交流讨论,触及知识盲区的问题队友都会很耐心解答,互帮互助的氛围让我从中学习到了不少。

    周丽榕:通过这次实践,汇总了之前所学到的微服务部署的相关内容,也懂得了如何真正的以微服务部署一个完整的项目。虽然在微服务部署上没有参与很多,但收获还是蛮多的。当然,在这门课程中也学到了很多,比如之前从未接触的docker,通过这次大作业实践,也让我更加了解docker。虽然这门课程已经接近尾声,但是我的学习之路还任重而道远。
    王瑞卿:通过本次实验,对之前的知识进行里重新总结综合,对镜像、容器特别是容器连接等知识更加熟练了并予以实践,也对微服务和其如何发挥作用有了更好的了解和学习。在实验过程中,学会了如何与队友沟通协作共同完成任务,意识到了自己还有很多需要学习的,在团队协作中也跟队友学到了很多,也十分感谢我的队友每次耐心地帮我一起解决问题。

  • 相关阅读:
    洛谷 P1244 青蛙过河
    洛谷 P1004 方格取数
    洛谷 CF894A QAQ
    【题解】洛谷 P5506 封锁
    洛谷 P3884 [JLOI2009]二叉树问题
    Bzoj4894 天赋
    Bzoj4893 项链分赃
    Bzoj3583 杰杰的女性朋友
    POJ3233 Matrix Power Series
    UOJ#204 【APIO2016】Boat
  • 原文地址:https://www.cnblogs.com/huckleberry/p/13201043.html
Copyright © 2020-2023  润新知