选题简介
我们小组这次大作业的主题是对目前疫情情况作出分析和展示,让用户能时刻掌握知晓目前疫情的发展情况。通过web访问页面可以了解到全国各地的疫情状况,包括现有确诊人数、累计确诊、累计治愈和累计死亡人数,以及各项较昨日的新增人数等。我们的web项目是基于docker以微服务完成项目部署。
项目设计
我们的web项目包括前端、后端和数据库三个部分
前端部分
前端页面通过vue来快速搭建,使用element-ui和echarts来搭建视图
项目代码详见GitHub仓库
微服务部署
- 获取nginx镜像
sudo docker pull nginx
- 在项目根目录下创建nginx文件夹,并将前端build后得到的dist文件夹放到nginx文件夹下
- 创建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 .
- 基于vuenginxcontainer镜像启动容器,运行命令如下:
sudo docker run -p 3000:80 -d --name vueApp vuenginxcontainer
- 此时前端在docker已经部署完成,构建镜像已上传到dockerhub 前端镜像
sudo docker commit -m 'add vueApp' vuenginxcontainer jamwongh/vuenginx
sudo docker login && docker push jamwongh/vuenginx
- 还未部署后端的前端页面访问
后端部分
项目代码详见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
- 将镜像push到dockerhub上 后端和数据库镜像
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!")
运行结果
三个部分的容器连接
采用docker compose来进行容器连接
- 将三个镜像全部pull下来
sudo docker pull jamwongh/vuenginx
sudo docker pull zxl2464331339/infect:project-latest2
sudo docker pull zxl2464331339/infect:mysql-v2
-
文件准备
-
创建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
- 查看三个容器是否正常运行
- 进入mysql2容器
sudo docker exec -it [容器ID] /bin/bash #进入容器
mysql -u root -p #登录mysql
create database COVID; #创建数据库
use COVID;
set names utf8;
source COVID.sql;
运行结果
- 先进行后端页面测试
- 前端页面测试
- 数据库展示
组内分工+贡献比
学号 | 姓名 | 分工 | 贡献比 |
---|---|---|---|
031702337 | 叶琦熠 | 爬虫,后端与前端代码改进 | 20% |
031702316 | 翟鑫亮 | 后端与数据库微服务部署 | 20% |
031702525 | 周鑫煌 | 前端微服务部署 | 20% |
031702301 | 王瑞卿 | 容器连接 | 15% |
031702312 | 鲍冰如 | 容器连接 | 15% |
031702313 | 周丽榕 | 数据库设计,撰写博客 | 10% |
总结
叶琦熠:通过本次的大作业,我熟练了之前学习过的一些爬虫知识并予以实践,以及学习了前端vue与后端代码接口的实现,巩固了之前所学习的微服务部署相关知识……通过这次的大作业,作为组长(虽然是老师默认指定的),我逐渐地学会如何与队员沟通以及做好队员与队员之间的分工协调工作,虽然还是有地方考虑的不周到,但还是得到了队员的包容与理解,团队氛围还算融洽,我也是得到了些成长吧。
鲍冰如:这次实验主要是运用此前学习到的微服务知识,将团队项目部署到微服务,对前后端以及数据库的连接有了更深的了解,遇到问题会和队友一起交流讨论,触及知识盲区的问题队友都会很耐心解答,互帮互助的氛围让我从中学习到了不少。
周丽榕:通过这次实践,汇总了之前所学到的微服务部署的相关内容,也懂得了如何真正的以微服务部署一个完整的项目。虽然在微服务部署上没有参与很多,但收获还是蛮多的。当然,在这门课程中也学到了很多,比如之前从未接触的docker,通过这次大作业实践,也让我更加了解docker。虽然这门课程已经接近尾声,但是我的学习之路还任重而道远。
王瑞卿:通过本次实验,对之前的知识进行里重新总结综合,对镜像、容器特别是容器连接等知识更加熟练了并予以实践,也对微服务和其如何发挥作用有了更好的了解和学习。在实验过程中,学会了如何与队友沟通协作共同完成任务,意识到了自己还有很多需要学习的,在团队协作中也跟队友学到了很多,也十分感谢我的队友每次耐心地帮我一起解决问题。
周鑫煌:本次大作业第一次尝试使用vue进行web前端开发,对现在逐渐兴起的大前端技术栈也有了更多的了解,希望今后有机会可以尝试用在跨平台混合开发上。最后通过docker部署vue前端程序也巩固了微服务的相关知识。
翟鑫亮:这次实验的后端主要是通过springboot技术框架结合微服务部署实现的,经过了为期一个多星期的学习后端技术,也了解到了一些项目开发的主要流程和逻辑框架,总的来说呢就是获益匪浅。此次项目是前后端分离的,由于处理的是后端,所以前端vue就没有接触,可以说算是个遗憾吧,有机会一定深入学习一下。另外这次作业也对提升我多人协作的能力很有帮助。最后还是蛮感谢我的组员他们的,每个人都在为这次的作业用尽了全部力量!