# takin **Repository Path**: zhangchenyan/takin ## Basic Information - **Project Name**: takin - **Description**: takin 是 一个 微服务 PRC 开发框架 - **Primary Language**: Java - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2022-04-26 - **Last Updated**: 2022-11-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: 分布式微服务, nacos, MyBatis, SpringBoot, rpc ## README # takin :elephant: :elephant: :elephant: :elephant: :elephant: :elephant: :elephant: :elephant: #### 介绍 ##### takin框架集成大多数互联网功能:统一异常、swagger、软删除、签名验签、分页封装、token验证、权限验证、日志集成、配置中心、服务注册发现、代码生成器maven插件是一个时候中小型企业开发的框架。
##### takin是主要基于spring boot,nacos,MybatisPlus,redis 开发的微服务RPC模式WEB开发框架,1.X版本已经上线发布到中央仓库。 ##### 1.1.2 支持分布式微服务部署、支持配置中心、注册中心服务注册和发现。-2022年5月16日 ##### 1.2.0 增加了事件总线 - 2022年9月19日 1.2.1升级nacos到最新2.1.1 ##### 规划中- #### 软件架构 ![输入图片说明](img/image.png) ##### 1.takin-auth-common 封装登录,登出,Token。 ##### 2.takin-auth-web 封装登录验证,签名验证,RABC权限验证。 ##### 3.takin-cache-redis 封装redis的使用。 ##### 4.takin-common 封装全局异常,时间格式化统一处理,Swagger2配置,OkHttp,接口统一返回对象等。 ##### 5.takin-config 封装了读取nacos配置和监听nacos配置变化。 ##### 6.takin-generator-maven-plugin 封装代码生成maven插件 ##### 7.takin-service-bus-common 封装logback日志配置,nacos服务注册发现,RPC调用解析方式,数据库实体、service接口基类、分页。 ##### 8.takin-service-bus-server provider服务层依赖---封装MybatisPlus,nacos服务注册,RpcController提供远程调用,。 ##### 9.takin-service-bus-client web层依赖---依赖封装nacos服务发现,Rpc远程调用。 #### 框架使用结构说明 ##### 开发项目主要分为3个MAVEN层结构,详情使用可以参考[基于takin开发的后台管理系统](https://gitee.com/zhangchenyan/takin-sys.git)源码 ![输入图片说明](img/image1.png) 1. contract契约层基于takin-service-bus-common 负责定义dto,entity,page,service接口。 2. provider服务层基于takin-service-bus-server 负责service接口实现,数据库的操作,业务相关实现。一个provider对应一个数据库实例。 3. web层基于takin-service-bus-client 负责api接口实现。 4. contract契约层maven依赖 ``` takin-sys com.gitee.zhangchenyan 1.0-SNAPSHOT 4.0.0 takin-sys-contract com.gitee.zhangchenyan takin-service-bus-common com.github.xiaoymin knife4j-spring-boot-starter ``` 5. provider服务层maven依赖 ``` takin-sys com.gitee.zhangchenyan 1.0-SNAPSHOT 4.0.0 takin-sys-provider 1.8 com.gitee.zhangchenyan takin-service-bus-server mysql mysql-connector-java com.gitee.zhangchenyan takin-sys-contract 1.0-SNAPSHOT compile jar org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok org.springframework.boot spring-boot-configuration-processor com.gitee.zhangchenyan takin-generator-maven-plugin ${takin.version} ``` 6. web层maven依赖 ``` takin-sys com.gitee.zhangchenyan 1.0-SNAPSHOT 4.0.0 takin-sys-web 1.8 8 8 com.gitee.zhangchenyan takin-service-bus-client com.gitee.zhangchenyan takin-auth-web com.gitee.zhangchenyan takin-sys-contract 1.0-SNAPSHOT compile org.springframework.boot spring-boot-starter-web jar org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok org.springframework.boot spring-boot-configuration-processor ``` #### 框架使用配置说明 ##### 1. [下载安装nacos](https://nacos.io/zh-cn/docs/deployment.html) 导入config目录下nacos配置根据实际情况修改,安装redis,安装数据库。 ##### 2. 配置nacos环境变量 ##### ![输入图片说明](img/image4.png) ##### 3. web层配置说明application.properties ``` server.port=9001 #配置读取电脑环境变量nacos地址 takin.nacosServerAddress=${NACOS_CONFIG_SERVER_ADDR} #配置应用名称,用于日志的生成文件名称和读取spring.application.name同名的配置文件 spring.application.name=takin-sys-web #项目开发过程远程调用可能会调用到其它开发者的服务层,可以指定服务层调用地址(nacos中public配置spring.profiles.active=dev才有效果) #takin.devContractPackage = com.gitee.zhangchenyan.takin.sys.service&127.0.0.1:5002;com.xx.service&127.0.0.1:5003 ``` ##### 4. provider层配置说明application.properties ``` server.port=9002 #配置读取电脑环境变量nacos地址 takin.nacosServerAddress=${NACOS_CONFIG_SERVER_ADDR} #配置应用名称,用于日志的生成文件名称和读取spring.application.name同名的配置文件 spring.application.name=takin-sys-provider #注册到nacos的服务名称,名称必须为contract模块的service包路径. takin.contractPackage = com.gitee.zhangchenyan.takin.sys.service #注册nacos服务地址【网络复杂的时候配置,默认为本机IP地址和server.port端口】 #takin.rpcServerIp = 127.0.0.1 #takin.rpcServerPort = 5002 ``` ##### 5. nacos配置文件说明-public为公共配置文件都可以读取。层级配置文件和spring.application.name名保持一致 ![img.png](img/img7.png) ##### 6. 代码自动生成maven插件 ![输入图片说明](img/image6.png) #### 核心使用说明 - 如下方描述不清楚,详情使用可以参考[基于takin开发的后台管理系统](https://gitee.com/zhangchenyan/takin-sys.git) 源码 ##### 1.接口统一返回Result对象,ResultUtils助手类 ![输入图片说明](img/image2.png) ##### 2.登录成功返回token对象,token为key可以使用header,cookie,session传入都可以 ![输入图片说明](img/image3.png) ##### 3.验证登录权限注解 - @AuthCheckLogin ##### 4.RABC权限验证实现AuthCheckPermissionParameter接口,配合AuthCheckPermission注解使用 ``` /** * @Deacription 获取当前用户所以权限 * @Author zl * @Date 2022/4/10 21:51 * @Version 1.0 **/ @Component public class AuthCheckPermissionParameterImpl implements AuthCheckPermissionParameter { private final AuthUserService authUserService; private final IJedisClient jedisClient; private final ISysRolesMenusService sysRolesMenusService = ServiceClient.create(ISysRolesMenusService.class); private final static String permissionKey = "takin_permission_"; public AuthCheckPermissionParameterImpl(AuthUserService authUserService, JedisClient jedisClient) { this.authUserService = authUserService; this.jedisClient = jedisClient; } @Override public List getPermissions() { String token = authUserService.getToken(); String redisPermissionStr = jedisClient.get(permissionKey + token); if (StringUtils.hasLength(redisPermissionStr)) { return JSON.parseObject(redisPermissionStr, new TypeReference>() { }); } SysUser sysUser = authUserService.getUser(SysUser.class); List permissions = sysRolesMenusService.getPermissionsByUserId(sysUser.getId()); jedisClient.set(permissionKey + token, 7200L, JSON.toJSONString(permissions)); return permissions; } } ``` ``` @AuthCheckLogin @AuthCheckPermission("sys:role:index") @GetMapping("getMenuByRoleId") @ApiOperation("根据roleId查询menuId") public Result> getMenuByRoleId(Long roleId) { return sysRolesMenusService.getMenuByRoleId(roleId); } ``` ##### 5.redis使用 ``` @Autowired private IJedisClient jedisClient; ``` ##### 6.签名使用-一般用于提供API接口给第三方使用,实现AuthCheckSignParameter接口获取签名过程的key配合Controller注解@AuthCheckSign ``` 签名方式如下: (1)第一步,设所有发送post json 的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序), 使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。 (2)在stringA最后拼接上key(得到stringSignTemp字符串,并对stringSignTemp进行md5运算得到小写的32值signValue。 (3)最后向header添加sign=signValue发起api请求。 注意:将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(只需要对第一层的数据排序,集合里面的集合不处理) ``` ``` /** * @Deacription 获取签名的key,Demo * @Author zl * @Date 2022/4/10 14:20 * @Version 1.0 **/ @Component public class AuthCheckSignParameterImpl implements AuthCheckSignParameter { @Override public String getKey() { return "Y!64Dq7d@OIBVLclBH%fdVKS0mwxyCsCICperKCQwMIPOBcELq*Dkx8PL5p5LBXR"; } } @AuthCheckSign @PostMapping("test2") @ApiOperation("测试签名") public Result test2(@RequestBody SysUser sysUser) { return ResultUtils.success(sysUser); } ``` ##### 6.服务调用方式 ``` private final ISysRoleService service = ServiceClient.create(ISysRoleService.class); ``` ##### 6.分页查询使用 ``` //ServiceImpl实现分页查询条件 @Override public Wrapper getPageWrapper(SysRolePageParam pageParam) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda() .like(StrUtil.isNotEmpty(pageParam.getName()), SysRole::getName, pageParam.getName()); return queryWrapper; } //Controller调用方式 service.getPage(pageParam); ``` ##### 7.swagger 集成knife4j-spring-boot-starter框架,/doc.html访问查看swagger。 ![img.png](img/img8.png) ![img.png](img/img9.png) ##### 8.事件总线(使用队列进行进程和进程间的通信) takin-event-bus ###### 1.事件总线基于kafka-clients开发,kafka是使用场景最多的消息队列。使用前请先熟悉kafka重要概念(生产者、消费者、消费组、分区) ###### 2.框架默认约定大于配置,只需要配置一个takin.kafka.bootstrap-servers 就可以了 ###### 配置:takin.kafka.bootstrap-servers = 127.0.0.1:9092 ###### 生产者 ![img.png](img/event-bus-1.png) ###### 消费者 ![img.png](img/event-bus-2.png) ![img.png](img/event-bus-3.png)