# lg-cloud **Repository Path**: sunli1103_admin/lg-cloud ## Basic Information - **Project Name**: lg-cloud - **Description**: 【java训练营作业10-Spring Cloud】第三阶段 分布式架构设计&微服务深入剖析模块四 SpringCloud组件设计原理及实战(上)本模块对SpringCloud的一些高级特性,例如链路追踪设计原理及Sleuth+Zipkin、Spring Cloud Alibaba等进行讲解。 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-05-16 - **Last Updated**: 2022-03-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 作业说明 ``` java高薪训练营作业10 阶段三-模块四 ``` #### 编程题 请同学们根据下面的业务描述和要求,使⽤第一代Spring Cloud核心组件完成项⽬构建、编码及测试。 ##### 业务描述 以注册、登录为主线,串联起验证码生成及校验、邮件发送、IP防暴刷、⽤户统一认证等功能。实现需基于Spring Cloud 微服务架构,技术涉及Nginx、Eureka、Feign(Ribbon、Hystrix)、Gateway、Config+Bus等。 **工程目录结构** ``` lagou-cloud lagou-common(共通模块) lagou-cloud-config(端口9006) lagou-cloud-eureka(端口8761,8762) lagou-cloud-gateway(端口9002) lagou-service-code(端口8081) lagou-service-email(端口8082) lagou-service-user(端口8080) lagou-cloud-static static(html页面) ``` ![image-20200516052649983](reference/md-images/image-20200516052649983.png) ![image-20200516170538039](reference/md-images/image-20200516170538039.png) **环境版本** ``` JDK 11 MySQL 5.7 SpringBoot 2.2.7.RELEASE SpringCloud Hoxton.SR4 RabbitMQ 3.8.3 Nginx 1.17.10 ``` ##### 测试 - 注册 ![video-1](reference/md-videos/register.mp4) - 登录 ![video-2](reference/md-videos/login.mp4) - 鉴权 未登录状态下,清空cookie,直接访问后台的邮件服务,验证无token情况下是否被⽹关拦截 ![video-3](reference/md-videos/auth.mp4) ##### 相关实现 ###### 注册 1)⽤户访问到登录⻚面,在登录⻚面中有注册新账号功能 ![image-20200516145722834](reference/md-images/image-20200516145722834.png) 2)点击“注册新账号“,跳转到注册页面 ![image-20200516145741706](reference/md-images/image-20200516145741706.png) 3)在注册⻚面,需要⽤户输入邮箱地址、密码、确认密码,然后点击”获取验证码“,系统会⽣成验证码,并向所输入的邮箱地址发送该验证码,⽤户拿到邮箱中的验证码输⼊后完成注册 ![image-20200516150033211](reference/md-images/image-20200516150033211.png) ![image-20200516150300836](reference/md-images/image-20200516150300836.png) ![image-20200516150138054](reference/md-images/image-20200516150138054.png) ![image-20200516151343405](reference/md-images/image-20200516151343405.png) ###### 规则如下 A:一分钟内只允许获取一次验证码(前端Js控制即可), ![image-20200516055818374](reference/md-images/image-20200516055818374.png) ![image-20200516150337406](reference/md-images/image-20200516150337406.png) 验证码为随机⽣成的6位数字,10分钟内有效 ![image-20200516060102953](reference/md-images/image-20200516060102953.png) ![image-20200516150300836](reference/md-images/image-20200516150300836.png) 验证码存储到mysql数据库中(因为⼤家未系统学习Redis,所以此处令牌存入数据库即可); ![image-20200516060038548](reference/md-images/image-20200516060038548.png) B:存储到mysql数据库之后,使⽤发邮件功能,将该验证码发送到所输⼊的邮箱地址中 ![image-20200516060229509](reference/md-images/image-20200516060229509.png) ![image-20200516060301450](reference/md-images/image-20200516060301450.png) ![image-20200516060345876](reference/md-images/image-20200516060345876.png) ![image-20200516060417108](reference/md-images/image-20200516060417108.png) ![image-20200516060445409](reference/md-images/image-20200516060445409.png) C:⽤户从邮箱中拿到验证码,点击注册时,需要进行校验,因为验证码已经存入数据库,此时只需要查询数据库中该邮箱地址对应的最近一次的验证码记录,校验验证码是否正确,是否超时,若有问题,准确提示给用户 ![image-20200516150647617](reference/md-images/image-20200516150647617.png) ![image-20200516150717716](reference/md-images/image-20200516150717716.png) ![image-20200516151044396](reference/md-images/image-20200516151044396.png) 4)注册成功后,根据 <⽤户邮箱+密码> 生成签发token令牌(此处生成一个UUID模拟即可),该token令牌存⼊入数据库(因为⼤家未系统学习Redis,所以此处令牌存入数据库即可),并写入cookie中(以后的每次请求都会在cookie中携带该token,⽹关过滤器通过验证token的合法性来确定用户请求是否合法,如果token合法,根据token取出用户信息---->邮箱),最后重定向到欢迎⻚面(显示邮箱地址) ![image-20200516151149320](reference/md-images/image-20200516151149320.png) ![image-20200516151218289](reference/md-images/image-20200516151218289.png) ![image-20200516151351552](reference/md-images/image-20200516151351552.png) ###### 登录 1)用户访问登录⻚面,在登录⻚面输入邮箱地址+密码 ![image-20200516151424647](reference/md-images/image-20200516151424647.png) 2)点击登录,后台对⽤名和密码进行验证,然后根据<用户邮箱+密码> ⽣成签发token令牌(此处生成⼀个UUID模拟即可),该token令牌存入数据库(因为⼤家未系统学习Redis,所以此处令牌存入数据库即可),并写入cookie中(以后的每次请求都会在cookie中携带该token,网关过滤器通过验证token的合法性来确定⽤户请求是否合法,如果token合法,根据token取出⽤户信息---->邮箱),最后重定向到欢迎⻚面(显示邮箱地址) ![image-20200516151533556](reference/md-images/image-20200516151533556.png) ![image-20200516151351552](reference/md-images/image-20200516151351552.png) ###### Nginx 占用端口:80 实现动静分离。将静态资源 html ⻚面存放至本地磁盘,数据请求统一经过 GateWay ⽹关路由到下游微服务。 ![image-20200516142430582](reference/md-images/image-20200516142430582.png) ![image-20200516140834951](reference/md-images/image-20200516140834951.png) ###### 静态资源(html⻚页⾯面) 访问前缀:/static/xxx.html ![image-20200516143555225](reference/md-images/image-20200516143555225.png) ![image-20200516143617959](reference/md-images/image-20200516143617959.png) ![image-20200516144331304](reference/md-images/image-20200516144331304.png) ###### GateWay ⽹关 占用端口:9002端口 数据请求前缀:/api/xxx 完成统⼀路由、IP防暴刷(限制单个客户端IP在最近X分钟内请求注册接⼝不能超过Y次)、统一认证(登录时验证⽤户名密码是否合法,合法调用户微服务生成token,写⼊cookie,并且携带邮箱地址重定向到欢迎⻚面;后续请求再到来时,验证客户端请求cookie中携带的token是否合法,合法则放⾏,此处不考虑token更新问题)等功能 统一路由 路径路由规则: /api/user/** 路由到用户微服务 /api/code/** 路由到验证码微服务 /api/email/** 路由到邮件微服务 ![image-20200516142412327](reference/md-images/image-20200516142412327.png) ![image-20200516141047777](reference/md-images/image-20200516141047777.png) IP防暴刷 ![image-20200516152215470](reference/md-images/image-20200516152215470.png) ![image-20200516152103188](reference/md-images/image-20200516152103188.png) 统一认证 ![image-20200516152336105](reference/md-images/image-20200516152336105.png) ![image-20200516152409833](reference/md-images/image-20200516152409833.png) ![image-20200516152447425](reference/md-images/image-20200516152447425.png) ###### 微服务接口 ![image-20200516153101641](reference/md-images/image-20200516153101641.png) ###### lagou-service-user 用户微服务 占⽤端口:8080 数据请求前缀:/api/user/** 提供注册接口、⽤户是否已注册接口、登录接口(⽣成token并入库,token写入cookie中)、查 询⽤户登录邮箱接口等 ![image-20200516153502617](reference/md-images/image-20200516153502617.png) ![image-20200516152842545](reference/md-images/image-20200516152842545.png) ![image-20200516152903895](reference/md-images/image-20200516152903895.png) ###### lagou-service-code 验证码微服务 占⽤端口:8081 数据请求前缀:/api/code/** ⽤于提供验证码生成、验证码校验等接口,同时调⽤邮件微服务发送验证码 ![image-20200516153421290](reference/md-images/image-20200516153421290.png) ![image-20200516153259556](reference/md-images/image-20200516153259556.png) ###### lagou-service-email 邮件微服务 占⽤端口:8082 数据请求前缀:/api/email/** 提供邮件发送功能,⽤于将生成的验证码发送到注册邮箱 ![image-20200516153557161](reference/md-images/image-20200516153557161.png) ![image-20200516153655501](reference/md-images/image-20200516153655501.png) ###### Spring Cloud Config+Bus 占⽤用端⼝口: 9006 共享的配置:数据库连接信息、邮件发送相关配置、IP防暴暴刷指标参数(X分钟的X,Y上限的Y) 注意:除去Eureka是2个实例例的集群模式,其他保持单实例例 ###### Config配置中⼼ 数据库配置 ![image-20200516142723741](reference/md-images/image-20200516142723741.png) 邮件发送相关配置 ![image-20200516142841719](reference/md-images/image-20200516142841719.png) ![image-20200516142911820](reference/md-images/image-20200516142911820.png) 防暴刷参数配置 ![image-20200516143008719](reference/md-images/image-20200516143008719.png) 对应微服务可以在⾃己的配置文件中直接使用${xxx.yyy}的方式取出使用 ![image-20200516143209353](reference/md-images/image-20200516143209353.png) ![image-20200516143108485](reference/md-images/image-20200516143108485.png) Bus ![image-20200516154104152](reference/md-images/image-20200516154104152.png) ###### 关于跨域 前文在 Html 静态⻚面中有ajax 请求数据API统一接⼝9002的地方,会涉及跨域问题,可以考虑将静态资源和数据请求接口放在同⼀个域名下,根据url前缀在nginx层进行区分。 ⽐如所有部署,包括nginx都在一台机器上 - 可以给机器设置一个域名 www.test.com - 静态资源访问 www.test.com/static/xxx.html - 数据API接口请求 www.test.com/api/xxx/yyy 通过/static和/api在nginx层进⾏区分 ![image-20200516142353107](reference/md-images/image-20200516142353107.png) ###### Nginx ``` worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name www.test.com; location / { root html; index index.html index.htm; } # 添加静态资源映射 location /static/ { # alias /Users/sunli/IdeaProjects/lagou-cloud-static/static/; alias html/lagou-cloud/static/; index login.html; } # 添加网关映射 location /api/ { proxy_pass http://127.0.0.1:9002/; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } include servers/*; } ``` ###### 数据库 ``` -- ---------------------------- -- Table structure for lagou_auth_code -- ---------------------------- DROP TABLE IF EXISTS `lagou_auth_code`; CREATE TABLE `lagou_auth_code` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', `code` varchar(6) NOT NULL COMMENT '验证码', `create_time` datetime NOT NULL COMMENT '创建时间', `email` varchar(64) NOT NULL COMMENT '邮箱地址', `expire_time` datetime DEFAULT NULL COMMENT '过期时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4; -- ---------------------------- -- Table structure for lagou_request -- ---------------------------- DROP TABLE IF EXISTS `lagou_request`; CREATE TABLE `lagou_request` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', `create_time` datetime NOT NULL COMMENT '创建时间', `ip` varchar(32) NOT NULL COMMENT 'ip地址', `path` varchar(255) NOT NULL COMMENT '请求地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=70 DEFAULT CHARSET=utf8mb4; -- ---------------------------- -- Table structure for lagou_token -- ---------------------------- DROP TABLE IF EXISTS `lagou_token`; CREATE TABLE `lagou_token` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', `create_time` datetime NOT NULL COMMENT '创建时间', `email` varchar(64) NOT NULL COMMENT '邮箱地址', `token` varchar(255) NOT NULL COMMENT '令牌', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4; -- ---------------------------- -- Table structure for lagou_user -- ---------------------------- DROP TABLE IF EXISTS `lagou_user`; CREATE TABLE `lagou_user` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', `create_time` datetime NOT NULL COMMENT '创建时间', `email` varchar(64) NOT NULL COMMENT '邮箱地址', `password` varchar(32) NOT NULL COMMENT '密码', PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4; SET FOREIGN_KEY_CHECKS = 1; ``` ##### 相关参考资料 Spring Cloud Gateway 之 Filter https://msd.misuland.com/pd/3255817928875969896