一. 中小项目特点和系统设计要点

中小软件项目有以下特点:

1. 中小项目系统通常部署在客户机房或者客户私有云池,少量部署在公有云

2. 系统访问客户为用户的系统管理员(管理配置系统),用户管理层(查看数据统计分析信息),用户员工(通常通过微信公众号和小程序访问特定模块),并发访问量不大,但业务逻辑可能比较复杂

3. 系统集成较多,需要集成大量外部系统和用户采购的硬件。软件后期修改项目较多

从软件架构四个维度分析:

1. 可用性:对数据保存性要求较高,需要做统计分析。对系统可用性要求普通,可承受短期服务不可用。故数据节点考虑备份,应用节点可以采用单点。

2. 可修改性:要求高,需要不停集成新第三方系统和新功能

3. 安全性:普通安全性要求,通过客户云池网闸防火墙控制外部访问,内部服务器安全由运维保证

4. 性能:中低性能要求,访问量不大。

采用第二代微服务技术开发,选择spring cloud作为微服务技术栈,前后端分离设计,后端只提供接口

二. Spring cloud框架相关技术

1. 注册中心eureka:每个微服务只需要知道注册中心的地址,向注册中心发送服务上线信息,并定期拉去服务列表就可以获取其他微服务的ip地址,编码时不用指定其他微服务的IP,可以使用rest template或者feign的方式实现RPC调用

2. API网关spring gateway:和spring cloud切合较好,配合eureka可以自动拉去微服务的rest接口,不需要代码配置。前端和客户端使用统一的网关地址可以访问所有微服务API

3. 配置中心nacos:阿里开源配置中心,相比本地用配置文件进行配置,集中配置中心可以实现可视化配置,集中配置,配置实时修改,配置共享等功能

4. API鉴权JWT token: 使用JWT token不使用cookie,一套接口实现前端,APP,第三方外部系统共用

三. 微服务和系统说明

1. eureka

在pom中增加eureka依赖:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

main方法中增加eureka server注解:

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {public static void main(String[] args) {SpringApplication.run(EurekaApplication.class, args);}}

其他微服务要注册到eureka需要在pom中配置依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

同时在配置文件中配置eureka地址:

eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${eureka.service.port}/eureka/
eureka.instance.prefer-ip-address=true
eureka.instance.hostname =${eureka.instance.hostname}

2. nacos配置中心

官方文档地址:https://nacos.io/zh-cn/docs/what-is-nacos.html

按文档部署好配置中心后,增加3个公共配置:

systemAdmin.properties中配置jwt token的加密密钥和jwt token的过期时间,redis.properties配置redis的连接鉴权信息,dataSource.properites配置mysql数据库的连接鉴权信息

在需要加载配置项的微服务中增加nacos依赖配置:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>0.2.1.RELEASE</version>
</dependency>

在bootstrap.properties中指定配置中心的ip地址以及加载的配置项:

spring.cloud.nacos.config.server-addr=${spring.cloud.nacos.config.server-addr}
spring.cloud.nacos.config.ext-config[0].data-id=systemAdmin.properties
spring.cloud.nacos.config.ext-config[0].refresh=true
spring.cloud.nacos.config.ext-config[1].data-id=dataSource.properties
spring.cloud.nacos.config.ext-config[2].data-id=redis.properties

在代码中使用配置项和普通配置文件配置没有区别使用@Value即可

3. gateway微服务

pom文件中配置spring gateway依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

配置文件中开启自动发现微服务接口和接口名称小写

spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.gateway.discovery.locator.lower-case-service-id=true

gateway中实现一个拦截器AuthFilter,对前端请求的jwt token进行解析,并调用system-admin服务判断该请求用户是否是合法用户并且具备该API的权限:

    @Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String url = exchange.getRequest().getURI().getPath();//跳过不需要验证的路径if(Arrays.asList(skipAuthUrls).contains(url)){return chain.filter(exchange);}//从请求头中取出tokenString token = exchange.getRequest().getHeaders().getFirst("Authorization");//未携带tokenif (token == null || token.isEmpty()) {ServerHttpResponse originalResponse = exchange.getResponse();originalResponse.setStatusCode(HttpStatus.OK);originalResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");byte[] response = "{\"code\": \"401\",\"msg\": \"no jwt token in request header\"}".getBytes(StandardCharsets.UTF_8);DataBuffer buffer = originalResponse.bufferFactory().wrap(response);return originalResponse.writeWith(Flux.just(buffer));}//取出token包含的身份String userId = restTemplate.getForEntity("http://system-admin/auth/checkPermission?token=" + token + "&&apiUrl= " + url, String.class).getBody();if(userId == null || userId.isEmpty()){ServerHttpResponse originalResponse = exchange.getResponse();originalResponse.setStatusCode(HttpStatus.OK);originalResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");byte[] response = "{\"code\": \"10002\",\"msg\": \"invalid token.\"}".getBytes(StandardCharsets.UTF_8);DataBuffer buffer = originalResponse.bufferFactory().wrap(response);return originalResponse.writeWith(Flux.just(buffer));}if(userId.equals("NoPermission")) {ServerHttpResponse originalResponse = exchange.getResponse();originalResponse.setStatusCode(HttpStatus.OK);originalResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");byte[] response = "{\"code\": \"401\",\"msg\": \"this user do not have the access permission\"}".getBytes(StandardCharsets.UTF_8);DataBuffer buffer = originalResponse.bufferFactory().wrap(response);return originalResponse.writeWith(Flux.just(buffer));}//将现在的request,添加当前身份ServerHttpRequest mutableReq = exchange.getRequest().mutate().header("Authorization-UserId", userId).build();ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();return chain.filter(mutableExchange);}

API白名单过滤中,设置登录和获取验证码接口可以不经过鉴权直接访问

4. system-admin鉴权微服务

system-admin主要提供鉴权相关接口,登录,验证码获取,校验权限等功能

(1)获取图片验证码

@GetMapping("/getCode")@ApiOperation(value = "获取图片验证码(有效期为60秒),返回数据为jpg图片", consumes = "application/x-www-form-urlencoded")public void getCode(HttpServletResponse response, HttpServletRequest request) throws IOException {String verifyCode = VerifyCodeUtil.generateVerifyCode(4);String uuid = UUID.randomUUID().toString().replaceAll("-", "");stringRedisTemplate.opsForHash().put(Constants.REDIS_PREFIX_IMG_CODE_UUID + uuid, "code", verifyCode);stringRedisTemplate.expire(Constants.REDIS_PREFIX_IMG_CODE_UUID + uuid, 60, TimeUnit.SECONDS);response.addHeader("imgcode-uuid", uuid);VerifyCodeUtil.outputImage(214, 80, response.getOutputStream(), verifyCode);}

由于不使用cookie,需要在图片验证码返回头中增加一个id,前端登录需要把这个id和图片验证码一起发回

(2)登录接口,校验用户名密码,生产JWT token返回给前端

(3)jwt token刷新接口,刷新token并把老的token放入黑名单

(4)检查权限接口,校验当前用户是否是合法用户并且具备相应的API访问权限

5. service1业务微服务demo

一个业务微服务的demo,打印一个hello world。构建完毕后通过API网关直接访问:localhost:30002/server1/hello,返回无权限。先获取验证码,然后登录获取token后,在访问请求的header中增加

Authorization: [你获取的token]

再次访问hello接口,返回打印的hello world

四. 完整demo源代码

git地址: https://github.com/liuxiang19870216/lxdemo_springcloud

使用Spring cloud框架完成中小信息化项目相关推荐

  1. Spring Cloud云服务架构 - common-service 项目构建过程

    2019独角兽企业重金招聘Python工程师标准>>> 我们将对common-service整个项目进行剖析,将整个构建的流程给记录下来,让更多的关注者来参考学习. 首先在构建spr ...

  2. (八)整合spring cloud云服务架构 - commonservice-eureka 项目构建过程

    我们针对于HongHu cloud的eureka项目做以下构建,整个构建的过程很简单,我会将每一步都构建过程记录下来,希望可以帮助到大家: 1. 创建一个名为particle-common-eurek ...

  3. (七)整合spring cloud云服务架构 - common-service 项目构建过程

    我们将对common-service整个项目进行剖析,将整个构建的流程给记录下来,让更多的关注者来参考学习. 首先在构建spring cloud的common-service之前,我们需要准备的技术: ...

  4. spring cloud 框架搭建

    一.spring cloud简介 Spring Cloud为开发人员提供了用于快速构建分布式系统中某些常见模式的工具(例如,配置管理,服务发现,断路器,智能路由,微代理,控制总线).分布式系统的协调产 ...

  5. Spring Cloud Hoxton 版本微服务项目搭建 admin 监控客户端

    Spring Cloud Hoxton 版本微服务项目搭建 admin 监控客户端 前言 在上一篇文章博主已经讲解了admin 管理中心服务项目如何创建,不会的话可以前往学习,传送门:Spring C ...

  6. Spring Cloud Alibaba 大型微服务项目实战

    作者介绍 程序员十三,多年一线开发经验,历任高级开发工程师.后端主程.技术部门主管等职位.同时也是开源项目的爱好者和贡献者.掘金优秀作者.CSDN 博客专家.实体图书作者.专栏作者.视频讲师. 小册介 ...

  7. Spring Cloud【Finchley】-11Feign项目整合Hystrix监控

    文章目录 概述 整合步骤 Step1.添加 spring-cloud-starter-netflix-hystrix Step2. 启动类增加@EnableCircuitBreaker或者@Enabl ...

  8. Spring Boot+Eureka+Spring Cloud微服务快速上手项目实战

    说明 我看了一些教程要么写的太入门.要么就是写的太抽象.真正好的文章应该是快速使人受益的而不是浪费时间.本文通过一个包括组织.部门.员工等服务交互的案例让刚接触spring cloud微服务的朋友快速 ...

  9. 4.Spring Cloud (Hoxton.SR8) 实战笔记—项目中细节实现 约束 注意事项、模块难点总结、Lambda表达式

    本文目录如下: 二.项目中细节实现 & 约束 & 注意事项 2.1 数据类型 规范的判断字符串是否为空 字符串替换涉及的正则表达式问题: Pattern.quote()方法的使用 字符 ...

最新文章

  1. 某32岁大厂程序员吐槽:简历通过率才30%!大龄韭菜该何去何从?网友:没那么严重,同32岁,简历通过率90%!...
  2. MYSQL5-7版本sql_mode=only_full_group_by问题
  3. 数据蒋堂 | “后半”有序的分组
  4. Kafka剖析(一):Kafka背景及架构介绍--转
  5. 智能胖墩机器人_探班新雅CDIE | 智能硬件“奇幻乐园”
  6. 编写可维护的JavaScript之避免使用全局变量
  7. JSP导入XML不成功的一个原因
  8. 百度新闻 谷歌新闻_每日新闻摘要:到目前为止,Google I / O提供的最佳信息
  9. 前端学习(2739):重读vue电商网站49之第三方库使用CDN
  10. 微信公众号开发--微信JS-SDK扫一扫功能
  11. vue watch 经常监听不到_Vue.js中 watch(深度监听)的最易懂的解释
  12. uni app 调用网络打印机_uni-app封装一个request请求
  13. 【报告分享】二次元衍生创作行业报告.pdf(附下载链接)
  14. Astute Graphics for Mac(ai创意插件合集)
  15. 小熊派鸿蒙开发版,小熊派IoT开发板系列教程合集
  16. 微信分销系统源码定制开发
  17. Android手机便携式wifi的使用及无线数据传输(主要针对XP系统)
  18. nofllow html5,NoFollow:高亮显示nofollow标签
  19. 视频剪辑-OpenShot
  20. 亚马逊账号被关联能申诉得回来吗

热门文章

  1. Note: NumExpr detected 12 cores but NUMEXPR_MAX_THREADS not set, so enforcing safe limit of 8. NumEx
  2. 空间路面matlab,基于Matlab的三维随机路面联合建模与仿真研究
  3. Java点名分类_java实现点名 | 学步园
  4. 图形世界分裂的两派 理清Direct3D和OpenGL的脉络
  5. 如何让全链路压测落地?
  6. uni-app开发的一些情况
  7. linux怎么新建html文件,HTML 编辑器
  8. FreeRDP的编译和使用。
  9. 上海往事之2015-07股市风云录
  10. 一些chrome调试