13 Commits
238 changed files with 2648 additions and 1174 deletions
+2 -3
View File
@@ -11,8 +11,7 @@
### 本地部署文档详见[ms开发文档](./all/ms/deploy.md)
## 项目概览
- `mybatis-generator-extend-maven-plugin`模块是便于快速根据条件生成mybatis-generator-plugin配置文件的maven扩展插件,基本增
删改查、按条件分页查询`dao` `servcie` `controller`层利用了词向量、卷积神经网络、使用人工智能技术进行代码语意分析(好吧,我吹不
下去了)自动生成,自动生成70%代码,降低开发中重复性耗时工作,此插件可在其他项目中单独使用。
删改查、按条件分页查询`dao` `servcie` `controller`层自动生成,自动生成70%代码,降低开发中重复性耗时工作,此插件可在其他项目中单独使用。
- 合理的拆分,拥有众多的可复用模块,开箱即用
- 高可用注册中心
- 高可用配置配置管理中心,通过`rabbitmq`支持配置刷新
@@ -25,7 +24,7 @@
- 支持docker容器部署
- 使用flume收集系统日志,便于日志分析
- 热点数据使用redis缓存
- 多数据源支持
- 多数据库,数据库分表支持
- 完善的项目使用文档
- 用心的开发者
## 整体技术选型
+10
View File
@@ -27,6 +27,16 @@
<artifactId>boot-starter-security-oauth</artifactId>
<version>${micro.fast.version}</version>
</dependency>
<dependency>
<groupId>com.micro.fast</groupId>
<artifactId>ms-upms-boot</artifactId>
<version>${micro.fast.version}</version>
</dependency>
<dependency>
<groupId>com.micro.fast</groupId>
<artifactId>ms-ucenter-boot</artifactId>
<version>${micro.fast.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
@@ -9,7 +9,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
* @author lsy
*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@MapperScan(basePackages = {"com.lishouyu.upms.dao"})
@MapperScan(basePackages = {"com.micro.fast.upms.dao","com.micro.fast.ucenter.dao"})
public class AllInOneApplication {
public static void main(String[] args) {
@@ -1,7 +0,0 @@
/**
* micro-fast pa common
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.ucenter.common;
@@ -1,7 +0,0 @@
/**
* micro-fast pa controller
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.ucenter.controller;
@@ -1,7 +0,0 @@
/**
* micro-fast pa dao
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.ucenter.dao;
@@ -1,7 +0,0 @@
/**
* micro-fast pa pojo
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.ucenter.pojo;
@@ -1,7 +0,0 @@
/**
* micro-fast pa service impl
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.ucenter.service.impl;
@@ -1,7 +0,0 @@
/**
* micro-fast pa service
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.ucenter.service;
@@ -1,7 +0,0 @@
/**
* micro-fast pa util
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.ucenter.util;
@@ -1,7 +0,0 @@
/**
* micro-fast cms vo
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.ucenter.vo;
@@ -1,7 +0,0 @@
/**
* micro-fast pa common
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.upms.common;
@@ -1,7 +0,0 @@
/**
* micro-fast pa controller
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.upms.controller;
@@ -1,7 +0,0 @@
/**
* micro-fast pa dao
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.upms.dao;
@@ -1 +0,0 @@
package com.lishouyu.upms;
@@ -1,7 +0,0 @@
/**
* micro-fast pa pojo
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.upms.pojo;
@@ -1,7 +0,0 @@
/**
* micro-fast pa service impl
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.upms.service.impl;
@@ -1,7 +0,0 @@
/**
* micro-fast pa service
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.upms.service;
@@ -1,7 +0,0 @@
/**
* micro-fast pa util
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.upms.util;
@@ -1,7 +0,0 @@
/**
* micro-fast cms vo
* @author lishouyu
* @version 1.0
* @since 1.0
*/
package com.lishouyu.upms.vo;
@@ -77,8 +77,8 @@ management:
# 自定义的配置参数
# --------------------------
mybatis:
typeAliasesPackage: com.lishouyu.upms.pojo
mappers: classpath:/mappers/*.xml
typeAliasesPackage: com.micro.fast.upms.pojo,com.micro.fast.ucenter.pojo
mappers: classpath*:/com/micro/fast/**/mapper/*.xml
pageHelperProperties:
- dialect:mysql
# boot-satrter-security-oauth模块自定义的配置
+7
View File
@@ -0,0 +1,7 @@
_ ___ _
(_) .' ..] / |_
_ .--..--. __ .---. _ .--. .--. ______ _| |_ ,--. .--. `| |-'
[ `.-. .-. | [ | / /'`\][ `/'`\]/ .'`\ \|______|'-| |-'`'_\ : ( (`\] | |
| | | | | | | | | \__. | | | \__. | | | // | |, `'.'. | |,
[___||__||__][___]'.___.'[___] '.__.' [___] \'-;__/[\__) )\__/ © 2018 https://gitee.com/kklt1996/micro-fast All Rights Reserved
+1
View File
@@ -0,0 +1 @@
FROM ubuntu:latest
Binary file not shown.
+1 -1
View File
@@ -1,2 +1,2 @@
#!/usr/bin/env bash
docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 25672:25672 -p 4369:4369 rabbitmq
docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 25672:25672 -p 4369:4369 -p 15672:15672 -p 15671:15671 rabbitmq:3-management
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
cd /opt/tools/kafka_2.11-1.1.0
bin/kafka-server-start.sh config/server.properties
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
cd /opt/tools/kafka_2.11-1.1.0
bin/zookeeper-server-start.sh config/zookeeper.properties
@@ -0,0 +1,8 @@
package com.micro.fast.boot.starter.common.annotation;
/**
* 用于拦截controller向数据库中存入操作日志的注解
* @author lsy
*/
public @interface ControllerLog {
}
+5 -1
View File
@@ -27,4 +27,8 @@ spring-boot提供了默认的启动时执行数据库脚本功能,指定`sprin
更多的数据源,像增加多个druid数据源一样增加`com.micro.fast.common.init.properties.SqlInitProperties`类的配置bean,然后满足上述
两个数据源时同样要求即可。
### 启用基于shardbatis的分表功能
- 通过设置shardbatis.configPath(shardbatis的xml配置文件的classpath路径)属性来激活分表功能.使用`@IdShard`来在mapper接口参数中指定分表策略字段
或者`@IdShard('filedName')`来指定参数对象中哪个字段是分表策略所需的字段.
- shardbatis.tableCount 指定分表的数量
- 注意,使用默认的分表策略的时候mapper接口中不允许使用只有一个map传递参数.
+10
View File
@@ -55,6 +55,16 @@
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
</dependency>
<!--分表插件-->
<dependency>
<groupId>org.shardbatis</groupId>
<artifactId>shardbatis</artifactId>
<version>2.0.0B</version>
</dependency>
<dependency>
<groupId>net.sf.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
</dependency>
<!--数据库连接-->
<dependency>
<groupId>mysql</groupId>
@@ -1,6 +1,7 @@
package com.micro.fast.common.config;
import com.github.pagehelper.PageHelper;
import com.google.code.shardbatis.plugin.ShardPlugin;
import com.micro.fast.common.config.param.MybatisParamConfig;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
@@ -8,6 +9,7 @@ import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@@ -48,6 +50,13 @@ public class SqlSessionFactoryConfig implements TransactionManagementConfigurer{
@Autowired
private MybatisParamConfig mybatisParamConfig;
/**
* 分表插件的配置
*/
@Autowired(required = false)
@Qualifier("shardPlugin")
private ShardPlugin shardPlugin;
/**
* mybatis连接工厂bean
* @return sqlSessionFactory
@@ -67,9 +76,7 @@ public class SqlSessionFactoryConfig implements TransactionManagementConfigurer{
//设置mapper映射文件的位置
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
sqlSessionFactoryBean.setMapperLocations(
resolver.getResources(mybatisParamConfig.getMappers()));
//resolver.getResources("classpath:/mappers/*.xml"));
sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mybatisParamConfig.getMappers()));
if (logger.isInfoEnabled()) {
logger.info("micro-fast common mybatisConfig: mappers:{}", mybatisParamConfig.getMappers());
}
@@ -98,7 +105,12 @@ public class SqlSessionFactoryConfig implements TransactionManagementConfigurer{
}
}
pageHelper.setProperties(properties);
sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper});
// 选择性启用shardbatisf分表插件
if (shardPlugin == null){
sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper});
} else {
sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper,shardPlugin});
}
//设置详细的配置
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
//开启下划线转驼峰命名
@@ -1,6 +1,5 @@
package com.micro.fast.common.dao;
package com.micro.fast.common.datasource.dynamic;
import com.micro.fast.common.config.DynamicDataSourceConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -1,6 +1,7 @@
package com.micro.fast.common.config;
package com.micro.fast.common.datasource.dynamic;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.micro.fast.common.datasource.dynamic.condition.MasterDataSourceCondition;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
@@ -13,12 +14,12 @@ import javax.sql.DataSource;
* @author lsy
*/
@Configuration
@AutoConfigureBefore(com.micro.fast.common.config.DynamicDataSourceConfig.class)
@AutoConfigureBefore(DynamicDataSourceConfig.class)
public class DruidDataSourceConfig {
@Bean(name = DynamicDataSourceConfig.MASTER_DATA_SOURCE)
@ConfigurationProperties("spring.datasource.druid.master")
@Conditional(com.micro.fast.common.condition.MasterDataSourceCondition.class)
@Conditional(MasterDataSourceCondition.class)
public DataSource masterDataSource(){
return DruidDataSourceBuilder.create().build();
}
@@ -1,4 +1,4 @@
package com.micro.fast.common.dao;
package com.micro.fast.common.datasource.dynamic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -18,7 +18,7 @@ public class DynamicDataSource extends AbstractRoutingDataSource{
@Override
public Object determineCurrentLookupKey() {
log.debug("数据源{}",DataSourceContextHolder.getDatdasourceName());
log.debug("数据源{}", DataSourceContextHolder.getDatdasourceName());
return DataSourceContextHolder.getDatdasourceName();
}
}
@@ -1,7 +1,7 @@
package com.micro.fast.common.config;
package com.micro.fast.common.datasource.dynamic;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import com.micro.fast.common.dao.DynamicDataSource;
import com.micro.fast.common.config.SqlSessionFactoryConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@@ -1,4 +1,4 @@
package com.micro.fast.common.annotation;
package com.micro.fast.common.datasource.dynamic.annotation;
import java.lang.annotation.*;
@@ -4,4 +4,4 @@
* @version 1.0
* @since 1.0
*/
package com.micro.fast.common.annotation;
package com.micro.fast.common.datasource.dynamic.annotation;
@@ -1,7 +1,7 @@
package com.micro.fast.common.aspect;
package com.micro.fast.common.datasource.dynamic.aspect;
import com.micro.fast.common.annotation.SwitchDataSource;
import com.micro.fast.common.dao.DataSourceContextHolder;
import com.micro.fast.common.datasource.dynamic.annotation.SwitchDataSource;
import com.micro.fast.common.datasource.dynamic.DataSourceContextHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
@@ -22,13 +22,13 @@ import java.lang.reflect.Method;
@Component
public class DynamicDataSourceAspect {
@Pointcut("@annotation(com.micro.fast.common.annotation.SwitchDataSource)")
@Pointcut("@annotation(com.micro.fast.common.datasource.dynamic.annotation.SwitchDataSource)")
public void mybatisExecutionSqlPointcut(){
}
/**
* 在SwitchDataSource注解的方法之前执行
* @see com.micro.fast.common.annotation.SwitchDataSource
* @see SwitchDataSource
*/
@Before("mybatisExecutionSqlPointcut()")
public void beforeMybatisExecutionSql(JoinPoint joinPoint){
@@ -58,7 +58,7 @@ public class DynamicDataSourceAspect {
/**
* 在SwitchDataSource注解的方法之后执行
* @see com.micro.fast.common.annotation.SwitchDataSource
* @see SwitchDataSource
*/
@After("mybatisExecutionSqlPointcut()")
public void afterMybatisExecutionSql(){
@@ -4,4 +4,4 @@
* @version 1.0
* @since 1.0
*/
package com.micro.fast.common.aspect;
package com.micro.fast.common.datasource.dynamic.aspect;
@@ -1,4 +1,4 @@
package com.micro.fast.common.condition;
package com.micro.fast.common.datasource.dynamic.condition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -0,0 +1 @@
package com.micro.fast.common.datasource.dynamic;
@@ -0,0 +1 @@
package com.micro.fast.common.datasource;
@@ -5,9 +5,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.io.IOException;
@@ -25,34 +23,11 @@ import java.util.Map;
*/
@Component
@Slf4j
public class InitUpmsSystem implements ApplicationListener<ContextRefreshedEvent> {
public static final String ANNOTATION_CONFIG_EMBEDDED_WEB_APPLICATION_CONTEXT = "AnnotationConfigEmbeddedWebApplicationContext";
public static final String ANNOTATION_CONFIG_APPLICATION_CONTEXT = "AnnotationConfigApplicationContext";
public class InitSystem implements CommandLineRunner {
@Autowired
@Autowired(required = false)
private Map<String,SqlInitProperties> sqlInitPropertiesMap;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
ApplicationContext applicationContext = event.getApplicationContext();
ApplicationContext parent = applicationContext.getParent();
// 保证springBoot上下文初始化完毕
if (applicationContext.getDisplayName().contains(ANNOTATION_CONFIG_EMBEDDED_WEB_APPLICATION_CONTEXT)
&& parent.getDisplayName().contains(ANNOTATION_CONFIG_APPLICATION_CONTEXT)) {
// 初始化数据表
sqlInitPropertiesMap.forEach((key,value) -> {
if (value != null) {
runInitSql(value.getDriverClassName(),value.getUrl(),value.getUsername(),value.getPassword(),value.getSqlPath());
}
});
log.info("name:{} displayName: {} parentName:{} parentName: {}",
applicationContext.getApplicationName(),
applicationContext.getDisplayName(),
parent.getApplicationName(),
parent.getDisplayName());
}
}
/**
* 执行初始化sql
* @param driver 数据库驱动全类名
@@ -80,4 +55,16 @@ public class InitUpmsSystem implements ApplicationListener<ContextRefreshedEvent
e.printStackTrace();
}
}
@Override
public void run(String... args) throws Exception {
if ( sqlInitPropertiesMap != null) {
// 初始化数据表
sqlInitPropertiesMap.forEach((key,value) -> {
if (value != null) {
runInitSql(value.getDriverClassName(),value.getUrl(),value.getUsername(),value.getPassword(),value.getSqlPath());
}
});
}
}
}
@@ -0,0 +1,10 @@
package com.micro.fast.common.plugin;
/**
* @author lsy
*/
public interface MetaObjectKey {
String DELEGATE_MAPPED_STATEMENT = "delegate.mappedStatement";
String DELEGATE_PARAMETER_HANDLER = "delegate.parameterHandler";
String DELEGATE_BOUND_SQL_SQL = "delegate.boundSql.sql";
}
@@ -0,0 +1,35 @@
package com.micro.fast.common.plugin;
/**
* mybatis插件工具类
* @author lsy
*/
public class PluginUtils {
/**
* 不能被实例化
*/
private PluginUtils(){
}
/**
* 根据语句id获取方法名
* @param statementId
* @return
*/
public static String getMethodName(String statementId){
int i = statementId.lastIndexOf(".");
return statementId.substring(i + 1);
}
/**
* 根据语句id获取全类名
* @param statementId
* @return
*/
public static String getClassName(String statementId){
int i = statementId.lastIndexOf(".");
return statementId.substring(0,i);
}
}
@@ -0,0 +1,18 @@
package com.micro.fast.common.plugin.lock.optimistic;
import lombok.Getter;
import lombok.Setter;
import java.lang.reflect.Field;
/**
* @author lsy
*/
@Getter
@Setter
public class CacheOptimisticLock {
private String fieldName;
private Field field;
}
@@ -0,0 +1,11 @@
package com.micro.fast.common.plugin.lock.optimistic;
/**
* 乐观锁插件运行时异常
* @author lsy
*/
public class OptimisticException extends RuntimeException {
public OptimisticException(String message) {
}
}
@@ -0,0 +1,14 @@
package com.micro.fast.common.plugin.lock.optimistic;
import java.lang.annotation.*;
/**
* @author lsy
* 加在方法上,表示方法使用乐观锁
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface OptimisticLock {
}
@@ -0,0 +1,17 @@
package com.micro.fast.common.plugin.lock.optimistic;
import java.lang.annotation.*;
/**
* @author lsy
* 运行时注解
* 可以加载字段和参数上
* 可以被继承
* 标识实体类哪个字段是乐观锁
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.PARAMETER})
@Documented
public @interface Version {
String value() default "";
}
@@ -0,0 +1,172 @@
package com.micro.fast.common.plugin.lock.optimistic;
import com.micro.fast.common.plugin.MetaObjectKey;
import com.micro.fast.common.plugin.PluginUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.sql.Connection;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
/**
* mybatis简单的乐观锁插件,不支持级联,不支持批量更新,仅支持单条数据的更新。
* 使用方式:
* 1. 给实体类上版本字段加上@Version
* 2. 给想要使用乐观锁的dao方法上加上@OptimisticLock注解
* 3. 使用dao方法的时候,更新对象要以实体类的对象为参数。
* 拦截StatementHandler类的prepare(Connection.class,Integer.class)方法
* @author lsy
*/
@Intercepts({@Signature(type= StatementHandler.class,method = "prepare",args = {Connection.class,Integer.class})})
public class VersionLock implements Interceptor {
/**
* 存储已经获取过的statementId 和 fieldName
*/
private static final ConcurrentHashMap<String,CacheOptimisticLock> cache = new ConcurrentHashMap<>();
/**
* 需要拦截的方法名
*/
public static final String PREPARE = "prepare";
/**
* sql 中的条件查询符号
*/
public static final String WHERE = "where";
/**
* 拦截器主体方法
* @param invocation 被拦截的方法的代理
* @return
* @throws Throwable
*/
@Override
public Object intercept(Invocation invocation) throws Throwable {
String interceptMethodName = invocation.getMethod().getName();
if (!PREPARE.equals(interceptMethodName)){
return invocation.proceed();
}
// 获取语句对象
StatementHandler statementHandler = (StatementHandler)invocation.getTarget();
// MetaObject是mybatis提供的简化插件开发的类
MetaObject metaObject = MetaObject.forObject(statementHandler,
SystemMetaObject.DEFAULT_OBJECT_FACTORY,
SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,
new DefaultReflectorFactory());
// 获取mapper接口实例,是否指定了乐观锁
MappedStatement mappedStatement = (MappedStatement)metaObject.getValue(MetaObjectKey.DELEGATE_MAPPED_STATEMENT);
String statementId = mappedStatement.getId();
// 是否已经获取过这个语句的对应的实体类的版本对象
StringBuilder fieldName = new StringBuilder();
BoundSql boundSql = statementHandler.getBoundSql();
// 获取原始的sql update tableName set a=123,b=234,c=345 where id = 123
String sql = boundSql.getSql();
// 获取参数对象实例,检查实体类是不是只有一个参数加了@Version注解
ParameterHandler parameterHandler = (ParameterHandler)metaObject.getValue(MetaObjectKey.DELEGATE_PARAMETER_HANDLER);
Object params = parameterHandler.getParameterObject();
String versionFieldValue = null;
// 已经获取过,肯定是乐观锁的语句
if(cache.contains(statementId)){
CacheOptimisticLock cacheOptimisticLock = cache.get(statementId);
Field field = cacheOptimisticLock.getField();
fieldName.append(cacheOptimisticLock.getFieldName());
field.setAccessible(true);
versionFieldValue = (String)field.get(params);
// 修改原本的sql
sql += " and" + fieldName.toString() + "=" + versionFieldValue;
int indexOfWhere = sql.indexOf(WHERE);
String begin = sql.substring(0, indexOfWhere);
String end = sql.substring(indexOfWhere);
String optimistVersionSql = begin + " ," + fieldName + "=" + (versionFieldValue+1) + " " + end;
metaObject.setValue(MetaObjectKey.DELEGATE_BOUND_SQL_SQL,optimistVersionSql);
return invocation.proceed();
}else{
String className = PluginUtils.getClassName(statementId);
String methodName = PluginUtils.getMethodName(statementId);
Class<?> aClass = Class.forName(className);
Method[] methods = aClass.getMethods();
// 获取实体类的全类名
String nameDO = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
// 找到mapper接口方法
Annotation[] annotations = method.getAnnotations();
boolean optimisticLock = false;
for (Annotation annotation : annotations) {
if (annotation.getClass() == OptimisticLock.class){
Parameter[] parameters = method.getParameters();
Parameter parameter = parameters[0];
nameDO = parameter.getName();
optimisticLock = true;
}
}
if (!optimisticLock){
return invocation.proceed();
}
break;
}
}
// 获取参数对象实例,检查实体类是不是只有一个参数加了@Version注解
Class<?> aClassDO = Class.forName(nameDO);
Field[] fields = aClassDO.getFields();
int haveOneVersionFlagfield = 0;
Field versionField = null;
for (Field field : fields) {
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType() == Version.class){
++ haveOneVersionFlagfield;
String name = field.getName();
fieldName.append(name);
versionField = field;
}
}
}
if (haveOneVersionFlagfield != 1){
throw new OptimisticException("请保证实体类有且只有一个属性加乐观锁版本注解");
}
// 突破属性的访问权限
versionField.setAccessible(true);
versionFieldValue = (String)versionField.get(params);
if (StringUtils.isBlank(versionFieldValue)){
throw new OptimisticException("请给版本控制属性赋值");
}
// 存储乐观锁
CacheOptimisticLock cacheOptimisticLock = new CacheOptimisticLock();
cacheOptimisticLock.setField(versionField);
cacheOptimisticLock.setFieldName(fieldName.toString());
cache.put(statementId,cacheOptimisticLock);
// 修改原本的sql
sql += " and" + fieldName.toString() + "=" + versionFieldValue;
int indexOfWhere = sql.indexOf(WHERE);
String begin = sql.substring(0, indexOfWhere);
String end = sql.substring(indexOfWhere);
String optimistVersionSql = begin + " ," + fieldName + "=" + (versionFieldValue+1) + " " + end;
metaObject.setValue(MetaObjectKey.DELEGATE_BOUND_SQL_SQL,optimistVersionSql);
return invocation.proceed();
}
}
@Override
public Object plugin(Object target) {
// 封装拦截器为插件,此拦截器只对StatementHandler和ParameterHandler生效,对执行器和ResultSetHandler不生效
return Plugin.wrap(target,this);
}
@Override
public void setProperties(Properties properties) {
// 给插件传递参数
}
}
@@ -0,0 +1,4 @@
/**
* mybatis扩展插件
*/
package com.micro.fast.common.plugin;
@@ -0,0 +1,13 @@
package com.micro.fast.common.shardbatis;
import java.lang.annotation.*;
/**
* 指定分表依据的参数的注解,分表的参数上必须有这个注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@Documented
public @interface IdShard{
String value() default "id";
}
@@ -0,0 +1,158 @@
package com.micro.fast.common.shardbatis;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
/**
* 根据idshard注解判断哪个参数是分表的依据,以及根据反射获取分表的依据参数的值
*
* @author lsy
*/
@Slf4j
public class IdShardUtils {
public static final String PARAM = "param";
/**
* 工具类私有构造防止被实例化
*/
private IdShardUtils() {
}
/**
* 根据statementId反射出方法,查找方法中带有IdShard朱姐标记的参数,获取其值用于分表策略
*
* @param params
* @param statementId
* @return
*/
public static Object getShardIdValue(Object params, String statementId) throws Exception {
int lastIndexOfD = statementId.lastIndexOf(".");
String methodName = statementId.substring(lastIndexOfD + 1);
String className = statementId.substring(0, lastIndexOfD);
Class<?> aClass = null;
try {
aClass = Class.forName(className);
Method[] methods = aClass.getMethods();
for (Method method : methods) {
String name = method.getName();
int parameterIndex = 0;
// 方法名相同就找到了语句
if (name.equals(methodName)) {
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
parameterIndex++;
// 参数是否包含IdShard.class注解
Annotation[] annotations = parameter.getAnnotations();
for (Annotation annotation : annotations) {
// 找到带有分表标记符号的参数
if (annotation.annotationType() == IdShard.class) {
Class<?> type = parameter.getType();
// statement是不是只有一个参数,有一个的参数的话参数类型应该相同.但是这一个参数不能是map类型
if (params.getClass() == type) {
return getValueByFieldName((IdShard) annotation,params);
} else {
// 如果有多个参数的话,mybatis会把参数封装成map类型,key是param+参数的顺序
String key = PARAM + (parameterIndex + 1);
Map<String,Object> map = (HashMap<String,Object>)params;
Object o = map.get(key);
return getValueByFieldName((IdShard) annotation,o);
}
}
}
}
}
}
} catch (ClassNotFoundException e) {
log.info("sql语句对应的类不存在:{}", e);
}
// 找不到就返回null
return null;
}
/**
* 根据注解和mybatis的参数
* @param idShard
* @param params
* @return
* @throws Exception
*/
private static Object getValueByFieldName(IdShard idShard, Object params) throws Exception {
// 如果是基础类型(表明是主键)就直接返回
if (isBasicType(params)) {
return params;
} else {
// 如果不是基础类型,就使用IdShard的value属性指定对象的哪个属性是分表策略需要的值
String shardFieldName = idShard.value();
if (StringUtils.isBlank(shardFieldName)) {
throw new Exception("the shardFieldName was not annotated");
}
Field field = null;
try {
// 根据字段名反射获取字段的类类型
field = params.getClass().getDeclaredField(shardFieldName);
} catch (NoSuchFieldException e) {
field = params.getClass().getSuperclass().getDeclaredField(shardFieldName);
}
// 设置属性的访问权限
field.setAccessible(true);
// 获取对象中属性的值
return field.get(params);
}
}
/**
*  检查参数是不是基础类型
*
* @param param
* @return
*/
private static boolean isBasicType(Object param) {
if (param == null) {
return false;
}
if (param instanceof String) {
return true;
}
if (param instanceof BigDecimal) {
return true;
}
if (param instanceof Integer) {
return true;
}
if (param instanceof Long) {
return true;
}
if (param instanceof Double) {
return true;
}
if (param instanceof Float) {
return true;
}
if (param instanceof Character) {
return true;
}
if (param instanceof Byte) {
return true;
}
if (param instanceof Short) {
return true;
}
if (param instanceof Boolean) {
return true;
}
return false;
}
}
@@ -0,0 +1,32 @@
package com.micro.fast.common.shardbatis.config;
import com.google.code.shardbatis.plugin.ShardPlugin;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
* shardbatis的配置
* @author lsy
*/
@Configuration
public class ShardbatisConfig {
/**
* shardPlugin的配置类,当这个配置属性不存在的时候分表插件不生效
* @param xmlClassPath shard
* @return
*/
@Bean(name = "shardPlugin")
@ConditionalOnProperty(prefix = "shardbatis",name = "configPath",matchIfMissing = false)
public ShardPlugin shardPlugin(@Value("${shardbatis.configPath}") String xmlClassPath){
ShardPlugin shardPlugin = new ShardPlugin();
Properties properties = new Properties();
properties.setProperty(ShardPlugin.SHARDING_CONFIG,xmlClassPath);
shardPlugin.setProperties(properties);
return shardPlugin;
}
}
@@ -0,0 +1,4 @@
/**
* shardbatis的java config 包
*/
package com.micro.fast.common.shardbatis.config;
@@ -0,0 +1,4 @@
/**
* 利用shardbatis实现分表
*/
package com.micro.fast.common.shardbatis;
@@ -0,0 +1,4 @@
/**
* shardbatis插件配置参数
*/
package com.micro.fast.common.shardbatis.properties;
@@ -0,0 +1,66 @@
package com.micro.fast.common.shardbatis.shardstrategy;
import com.google.code.shardbatis.strategy.ShardStrategy;
import com.micro.fast.common.config.SqlSessionFactoryConfig;
import com.micro.fast.common.shardbatis.IdShardUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Configuration;
/**
* 提供默认的分表策略
* @author lsy
*/
@Slf4j
@Configuration
@AutoConfigureBefore(SqlSessionFactoryConfig.class)
public class SsmDefaultShardStrategy implements ShardStrategy{
private static Integer tableCount;
/**
* 分表策略的实现
* @param baseTableName 逻辑表名
* @param params mybatis语句的参数
* @param statementId 语句的id,一般是类名.方法名
* @return 
*/
@Override
public String getTargetTableName(String baseTableName, Object params, String statementId) {
StringBuilder shardTableName = new StringBuilder(baseTableName);
shardTableName.append("_");
try {
Object shardIdValue = IdShardUtils.getShardIdValue(params, statementId);
if (shardIdValue == null){
shardTableName.append("000");
}else {
String s = shardIdValue.toString();
Integer integer = Integer.valueOf(s);
Integer index = integer % tableCount;
if (index<10){
shardTableName.append("00"+index);
} else if (index<100){
shardTableName.append("0"+index);
} else {
shardTableName.append(index);
}
}
} catch (Exception e) {
log.info("分表失败:{}",e);
throw new RuntimeException("分表失败");
}
return shardTableName.toString();
}
/**
* springBoot不允许直接给静态变量赋值,但是可以通过非静态方法给静态变量赋值
* @param tableCount
*/
@Value("${shardbatis.tableCount}")
public void setTableCount(Integer tableCount){
SsmDefaultShardStrategy.tableCount = tableCount;
}
}
@@ -0,0 +1,4 @@
/**
*提供默认的分表策略
*/
package com.micro.fast.common.shardbatis.shardstrategy;
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE shardingConfig PUBLIC
"-//shardbatis.googlecode.com//DTD Shardbatis 2.0//EN"
"http://shardbatis.googlecode.com/dtd/shardbatis-config.dtd">
<!-- shardbatis的示例配置-->
<shardingConfig>
<ignoreList>
<value></value>
</ignoreList>
<!-- parseList可选配置 如果配置了parseList,只有在parseList范围内并且不再ignoreList内的sql才会被解析和修改 -->
<parseList>
<value>xxx.dao.UserMapper.insertSelective</value>
<value>xxx.dao.UserMapper.selectByPrimaryKey</value>
<value>xxx.UserMapper.updateByPrimaryKeySelective</value>
</parseList>
<!-- 配置分表策略 tableName指的是实际的表名,strategyClass对应的分表策略实现类 -->
<strategy tableName="user" strategyClass="xxx.UserShardStrategyImpl"/>
</shardingConfig>
@@ -0,0 +1,7 @@
_ ___ _
(_) .' ..] / |_
_ .--..--. __ .---. _ .--. .--. ______ _| |_ ,--. .--. `| |-'
[ `.-. .-. | [ | / /'`\][ `/'`\]/ .'`\ \|______|'-| |-'`'_\ : ( (`\] | |
| | | | | | | | | \__. | | | \__. | | | // | |, `'.'. | |,
[___||__||__][___]'.___.'[___] '.__.' [___] \'-;__/[\__) )\__/ © 2018 https://gitee.com/kklt1996/micro-fast All Rights Reserved
@@ -7,6 +7,8 @@ import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 网关web配置类
* @author lsy
@@ -2,7 +2,7 @@ package com.micro.fast.gateway.controller;
import com.micro.fast.boot.starter.common.response.ServerResponse;
import com.micro.fast.gateway.filter.RecordInformationFilter;
import com.micro.fast.gateway.pojo.ServiceRank;
import com.micro.fast.gateway.pojo.vo.ServiceRank;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
@@ -0,0 +1,29 @@
package com.micro.fast.gateway.feign;
import com.micro.fast.boot.starter.common.response.ServerResponse;
import com.micro.fast.gateway.feign.fallback.SystemFeignFallBack;
import feign.Param;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* <pre>
* 远程获取系统信息的类
* upms 权限管理系统
* </pre>
* @author lsy
*/
@FeignClient(fallback = SystemFeignFallBack.class,name = "upms")
public interface SystemFeign {
/**
* 根据系统的路由查询系统的状态
* @param route 用户的访问路由
* @return
*/
@GetMapping("/upmsSystem/getSystemStatusByRoute")
ServerResponse<Integer> getSystemStatusByPath(@RequestParam("route") String route);
}
@@ -0,0 +1,13 @@
package com.micro.fast.gateway.feign.fallback;
import com.micro.fast.boot.starter.common.response.ServerResponse;
import com.micro.fast.gateway.feign.SystemFeign;
import org.springframework.stereotype.Component;
@Component
public class SystemFeignFallBack implements SystemFeign {
@Override
public ServerResponse getSystemStatusByPath(String path) {
return ServerResponse.errorMsg("系统繁忙,请稍后再试");
}
}
@@ -27,7 +27,7 @@ public class PreRequestFilter extends ZuulFilter {
@Override
public int filterOrder() {
return 1;
return 2;
}
@Override
@@ -39,6 +39,10 @@ public class PreRequestFilter extends ZuulFilter {
public Object run() {
//校验登录状态和访问权限
RequestContext requestContext = RequestContext.getCurrentContext();
// 如果上一个过滤器终止请求,则终止请求
if (requestContext.get(SystemIsOpenFilter.IS_SUCCESS).equals(false)){
return null;
}
HttpServletRequest request = requestContext.getRequest();
ServerResponse validate = ValidateJwtToken.validate(request, signingKey);
if (validate.isSuccess()) {
@@ -2,16 +2,12 @@ package com.micro.fast.gateway.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Set;
import java.util.SortedMap;
/**
* 对服务访问者的信息进行记录
@@ -0,0 +1,71 @@
package com.micro.fast.gateway.filter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.micro.fast.boot.starter.common.response.ServerResponse;
import com.micro.fast.gateway.service.SystemService;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* 判断服务是否停止访问的过滤器
* @author lsy
*/
@Component
@Slf4j
public class SystemIsOpenFilter extends ZuulFilter {
public static final String IS_SUCCESS = "isSuccess";
@Autowired
private SystemService systemService;
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
// 获取当前请求对象
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletRequest request = currentContext.getRequest();
// 获取请求服务的路由
String requestURI = request.getRequestURI();
String[] split = requestURI.split("/");
// 根据系统路由查找系统的开放状态
boolean b = systemService.systemIsOpen("/" + split[1]);
if (b){
currentContext.setSendZuulResponse(true);
currentContext.set(IS_SUCCESS,true);
} else{
// 终止请求
currentContext.setSendZuulResponse(false);
currentContext.setResponseStatusCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
ObjectMapper objectMapper = new ObjectMapper();
try {
currentContext.setResponseBody(objectMapper.writeValueAsString(ServerResponse.errorMsg("system is closed")));
currentContext.set(IS_SUCCESS,false);
} catch (JsonProcessingException e) {
log.info("对象转换成json失败");
}
}
return null;
}
}
@@ -1,4 +1,4 @@
package com.micro.fast.gateway.pojo;
package com.micro.fast.gateway.pojo.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -0,0 +1,9 @@
package com.micro.fast.gateway.service;
/**
* 查询系统信息的服务类
* @author lsy
*/
public interface SystemService {
boolean systemIsOpen(String path);
}
@@ -0,0 +1,46 @@
package com.micro.fast.gateway.service.impl;
import com.micro.fast.boot.starter.common.response.ServerResponse;
import com.micro.fast.gateway.feign.SystemFeign;
import com.micro.fast.gateway.service.SystemService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
public class SystemServiceImpl implements SystemService{
public static final String GATEWAY_SYSTEM_STATUS = "gateway:systemStatus:";
public static final int OPEN = 1;
@Autowired
private SystemFeign systemFeign;
@Autowired
private RedisTemplate<String,String> redisTemplate;
@Override
public boolean systemIsOpen(String path) {
// 尝试从缓存中获取系统的状态
String status = redisTemplate.opsForValue().get(GATEWAY_SYSTEM_STATUS + path);
if (StringUtils.isBlank(status)){
// 如果没有缓存,尝试从远程获取
ServerResponse<Integer> systemStatusByPath = systemFeign.getSystemStatusByPath(path);
if (systemStatusByPath.isSuccess()){
// 获取成功就进行缓存
Integer data = systemStatusByPath.getData();
redisTemplate.opsForValue().set(GATEWAY_SYSTEM_STATUS+path,String.valueOf(data),60, TimeUnit.SECONDS);
return OPEN == data;
} else {
return false;
}
} else {
return Integer.valueOf(status) == OPEN;
}
}
}
+7
View File
@@ -0,0 +1,7 @@
_ ___ _
(_) .' ..] / |_
_ .--..--. __ .---. _ .--. .--. ______ _| |_ ,--. .--. `| |-'
[ `.-. .-. | [ | / /'`\][ `/'`\]/ .'`\ \|______|'-| |-'`'_\ : ( (`\] | |
| | | | | | | | | \__. | | | \__. | | | // | |, `'.'. | |,
[___||__||__][___]'.___.'[___] '.__.' [___] \'-;__/[\__) )\__/ © 2018 https://gitee.com/kklt1996/micro-fast All Rights Reserved
@@ -0,0 +1,7 @@
_ ___ _
(_) .' ..] / |_
_ .--..--. __ .---. _ .--. .--. ______ _| |_ ,--. .--. `| |-'
[ `.-. .-. | [ | / /'`\][ `/'`\]/ .'`\ \|______|'-| |-'`'_\ : ( (`\] | |
| | | | | | | | | \__. | | | \__. | | | // | |, `'.'. | |,
[___||__||__][___]'.___.'[___] '.__.' [___] \'-;__/[\__) )\__/ © 2018 https://gitee.com/kklt1996/micro-fast All Rights Reserved
@@ -0,0 +1,7 @@
_ ___ _
(_) .' ..] / |_
_ .--..--. __ .---. _ .--. .--. ______ _| |_ ,--. .--. `| |-'
[ `.-. .-. | [ | / /'`\][ `/'`\]/ .'`\ \|______|'-| |-'`'_\ : ( (`\] | |
| | | | | | | | | \__. | | | \__. | | | // | |, `'.'. | |,
[___||__||__][___]'.___.'[___] '.__.' [___] \'-;__/[\__) )\__/ © 2018 https://gitee.com/kklt1996/micro-fast All Rights Reserved
@@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.PathVariable;
* 远程获取用户信息
* @author lsy
*/
@FeignClient(name = "upms",fallback = UpmsUserServiceFallback.class)
@FeignClient(fallback = UpmsUserServiceFallback.class,name= "upms")
public interface UpmsUserService {
/**
@@ -5,6 +5,7 @@ import com.micro.fast.oauth.dto.UpmsUser;
import com.micro.fast.oauth.feign.UpmsUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
+7
View File
@@ -0,0 +1,7 @@
_ ___ _
(_) .' ..] / |_
_ .--..--. __ .---. _ .--. .--. ______ _| |_ ,--. .--. `| |-'
[ `.-. .-. | [ | / /'`\][ `/'`\]/ .'`\ \|______|'-| |-'`'_\ : ( (`\] | |
| | | | | | | | | \__. | | | \__. | | | // | |, `'.'. | |,
[___||__||__][___]'.___.'[___] '.__.' [___] \'-;__/[\__) )\__/ © 2018 https://gitee.com/kklt1996/micro-fast All Rights Reserved
@@ -11,4 +11,4 @@ create table IF NOT EXISTS oauth_client_details (
additional_information VARCHAR(4096),
autoapprove VARCHAR(256)
);
INSERT INTO oauth_client_details VALUE ('ms',NULL ,'ms','all,write,read','code,password,custom,refresh_token',NULL ,NULL ,NULL ,NULL,NULL ,NULL);
# INSERT INTO oauth_client_details VALUE ('ms',NULL ,'ms','all,write,read','code,password,custom,refresh_token',NULL ,NULL ,NULL ,NULL,NULL ,NULL);
@@ -0,0 +1,7 @@
_ ___ _
(_) .' ..] / |_
_ .--..--. __ .---. _ .--. .--. ______ _| |_ ,--. .--. `| |-'
[ `.-. .-. | [ | / /'`\][ `/'`\]/ .'`\ \|______|'-| |-'`'_\ : ( (`\] | |
| | | | | | | | | \__. | | | \__. | | | // | |, `'.'. | |,
[___||__||__][___]'.___.'[___] '.__.' [___] \'-;__/[\__) )\__/ © 2018 https://gitee.com/kklt1996/micro-fast All Rights Reserved
@@ -0,0 +1,7 @@
_ ___ _
(_) .' ..] / |_
_ .--..--. __ .---. _ .--. .--. ______ _| |_ ,--. .--. `| |-'
[ `.-. .-. | [ | / /'`\][ `/'`\]/ .'`\ \|______|'-| |-'`'_\ : ( (`\] | |
| | | | | | | | | \__. | | | \__. | | | // | |, `'.'. | |,
[___||__||__][___]'.___.'[___] '.__.' [___] \'-;__/[\__) )\__/ © 2018 https://gitee.com/kklt1996/micro-fast All Rights Reserved
@@ -1,6 +1,6 @@
FROM registry.cn-hangzhou.aliyuncs.com/lishouyu/hub:javaV0.0.1
ADD ./target/ms-ucenter.jar /workhome/app.jar
ADD ./cmd-dev.sh /workhome/cmd-dev.sh
ADD ../target/ms-ucenter.jar /workhome/app.jar
ADD cmd-dev.sh /workhome/cmd-dev.sh
RUN set -xe && chmod u+x /workhome/cmd-dev.sh
ENV JAVA_HOME /opt/lib/jdk1.8.0_144
ENV JAVA_JRE ${JAVA_HOME}/jre
+102
View File
@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>ms-ucenter-app</artifactId>
<packaging>jar</packaging>
<name>ms-ucenter-app</name>
<description>ucenter-app</description>
<parent>
<groupId>com.micro.fast</groupId>
<artifactId>ucenter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.micro.fast</groupId>
<artifactId>ms-ucenter-feign</artifactId>
<version>${micro.fast.version}</version>
</dependency>
<!--监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</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-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--熔断,断的是这个服务调用其他服务时失败的时候断-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--调用其他服务的时候熔断情况的图形化展示-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<!--配置客户端配置刷新-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<!--请求重试-->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<!--检测生成服务调用数据-->
<!--<dependency>-->
<!--<groupId>org.springframework.cloud</groupId>-->
<!--<artifactId>spring-cloud-starter-zipkin</artifactId>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin-stream</artifactId>
</dependency>
<!--测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
<finalName>ms-ucenter</finalName>
</build>
</project>
@@ -0,0 +1,7 @@
_ ___ _
(_) .' ..] / |_
_ .--..--. __ .---. _ .--. .--. ______ _| |_ ,--. .--. `| |-'
[ `.-. .-. | [ | / /'`\][ `/'`\]/ .'`\ \|______|'-| |-'`'_\ : ( (`\] | |
| | | | | | | | | \__. | | | \__. | | | // | |, `'.'. | |,
[___||__||__][___]'.___.'[___] '.__.' [___] \'-;__/[\__) )\__/ © 2018 https://gitee.com/kklt1996/micro-fast All Rights Reserved
@@ -1,31 +1,31 @@
# 从配置中心加载文件
spring:
cloud:
config:
profile: dev
label: master
name: ucenter
uri: http://config:server@www.config.com:10000/
# 实现配置中心的高可用
discovery:
service-id: config-server
enabled: false
username: config
password: server
# 从配置中心加载服务失败重试,此设置可以降低部署难度可以较好的支持docker部署,合理进行配置后,部署时应用启动顺序不会影响程序是否启动成功
# 但会牺牲配置中心的高可用。在服务较少的时候可采用此配置。在微服务数量数量巨大时应选用配置中心高可用,按顺序启动微服务
fail-fast: true
retry:
max-attempts: 30
initial-interval: 2000
multiplier: 1.18
max-interval: 30000
eureka:
client:
serviceUrl:
defaultZone: http://micro:fast@www.register1.com:10002/eureka/,http://micro:fast@www.register2.com:10004/eureka/ #配置所有的注册中心
instance:
hostname: www.ucenter.com
# 配置熔断监控的集群名称
metadata-map:
# 从配置中心加载文件
spring:
cloud:
config:
profile: dev
label: master
name: ucenter
uri: http://config:server@www.config.com:10000/
# 实现配置中心的高可用
discovery:
service-id: config-server
enabled: false
username: config
password: server
# 从配置中心加载服务失败重试,此设置可以降低部署难度可以较好的支持docker部署,合理进行配置后,部署时应用启动顺序不会影响程序是否启动成功
# 但会牺牲配置中心的高可用。在服务较少的时候可采用此配置。在微服务数量数量巨大时应选用配置中心高可用,按顺序启动微服务
fail-fast: true
retry:
max-attempts: 30
initial-interval: 2000
multiplier: 1.18
max-interval: 30000
eureka:
client:
serviceUrl:
defaultZone: http://micro:fast@www.register1.com:10002/eureka/,http://micro:fast@www.register2.com:10004/eureka/ #配置所有的注册中心
instance:
hostname: www.ucenter.com
# 配置熔断监控的集群名称
metadata-map:
cluster: ms-ucenter
+35
View File
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>ms-ucenter-boot</artifactId>
<packaging>jar</packaging>
<name>ms-ucenter-boot</name>
<description>ucenter-common-boot</description>
<parent>
<groupId>com.micro.fast</groupId>
<artifactId>ucenter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.micro.fast</groupId>
<artifactId>ms-ucenter-web</artifactId>
<version>${micro.fast.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
<finalName>ms-ucenter-boot</finalName>
</build>
</project>
@@ -0,0 +1,15 @@
package com.micro.fast.ucenter;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class BootUcenterApplication {
public static void main(String[] args) {
SpringApplication.run(BootUcenterApplication.class, args);
}
}
@@ -0,0 +1,2 @@
# 自动化装配
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.micro.fast.ucenter.BootUcenterApplication
+35
View File
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>ms-ucenter-common</artifactId>
<packaging>jar</packaging>
<name>ms-ucenter-common</name>
<description>ucenter-common</description>
<parent>
<groupId>com.micro.fast</groupId>
<artifactId>ucenter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
<finalName>ms-ucenter</finalName>
</build>
</project>

Some files were not shown because too many files have changed in this diff Show More