# 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
##### 规划中-
#### 软件架构

##### 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)源码

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环境变量
##### 
##### 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名保持一致

##### 6. 代码自动生成maven插件

#### 核心使用说明 - 如下方描述不清楚,详情使用可以参考[基于takin开发的后台管理系统](https://gitee.com/zhangchenyan/takin-sys.git) 源码
##### 1.接口统一返回Result对象,ResultUtils助手类

##### 2.登录成功返回token对象,token为key可以使用header,cookie,session传入都可以

##### 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。


##### 8.事件总线(使用队列进行进程和进程间的通信) takin-event-bus
###### 1.事件总线基于kafka-clients开发,kafka是使用场景最多的消息队列。使用前请先熟悉kafka重要概念(生产者、消费者、消费组、分区)
###### 2.框架默认约定大于配置,只需要配置一个takin.kafka.bootstrap-servers 就可以了
###### 配置:takin.kafka.bootstrap-servers = 127.0.0.1:9092
###### 生产者

###### 消费者

