美团开源的leaf:https://tech.meituan.com/2017/04/21/mt-leaf.html
github地址:https://github.com/Meituan-Dianping/Leaf
官方提供了两种方式,雪花算法和数据库。目前仅提供数据库方式获取分布式id.
引入依赖:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--leaf-core 核心依赖-->
<dependency>
<groupId>com.sankuai.inf.leaf</groupId>
<artifactId>leaf-core</artifactId>
<version>1.0.1</version>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
spring:
profiles:
active: dev
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://33.33.33.33:3306/xxx?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true
username: root
password: 123
initial-size: 5
min-idle: 1
max-active: 5
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 30000
max-evictable-idle-time-millis: 60000
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
@EnableDiscoveryClient
@EnableFeignClients
public class AppMain {
SpringApplication app = new SpringApplication(AppMain.class);
log.info("Registering ShutDonw Hook.");
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
log.info("Shutting down service, unregister from Eureka server!");
DiscoveryManager.getInstance().getEurekaClient().shutdown();
}
});
}
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.sankuai.inf.leaf.segment.SegmentIDGenImpl;
import com.sankuai.inf.leaf.segment.dao.impl.IDAllocDaoImpl;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = {"com.sankuai.inf.leaf.segment.dao", "com.xxx.xx.mapper"})
public class DataSourceConfig {
@Autowired
private Environment environment ;
/**
* 配置单表数据源
* @return
*/
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource(){
return DruidDataSourceBuilder.create().build(environment, "spring.datasource");
}
@Bean
public IDAllocDaoImpl idAllocDao(DataSource dataSource) {
return new IDAllocDaoImpl(dataSource);
}
@Bean
public SegmentIDGenImpl segmentIDGen(IDAllocDaoImpl idAllocDao) {
SegmentIDGenImpl segmentIDGen = new SegmentIDGenImpl();
segmentIDGen.setDao(idAllocDao);
segmentIDGen.init();
return segmentIDGen;
}
}
import com.sankuai.inf.leaf.segment.model.LeafAlloc;
import org.apache.ibatis.annotations.Update;
public interface LeafAllocMapper {
@Update("INSERT INTO leaf_alloc (biz_tag, max_id, step) values (#{key},#{maxId},#{step})")
void create(LeafAlloc leafAlloc);
}
@RestController
@RequestMapping("/api")
public class IdGenServiceApi {
private final Logger log = LoggerFactory.getLogger(IdGenServiceApi.class);
@Autowired
private SegmentIDGenImpl segmentIDGen;
@Autowired
private LeafAllocMapper leafAllocMapper;
@GetMapping({"/getId"})
public ResponseEntity<Result> getNextId(@RequestParam("biz") String biz) {
Result result = segmentIDGen.get(biz);
return ResponseEntity.ok(result);
}
@GetMapping({"/getIdBatch"})
public ResponseEntity<List<Long>> getNextIdBatch(@RequestParam("biz") String biz, @RequestParam("count") Integer count) {
if(count <= 0 || count > 200) {
throw new Exception("获取失败");
}
List<Long> list = new ArrayList<>();
for (int i = 0; i < count; i++) {
Result result = segmentIDGen.get(biz);
list.add(result.getId());
}
return ResponseEntity.ok(list);
}
@PostMapping("/create")
public ResponseEntity<LeafAlloc> create(@RequestBody LeafAlloc leafAlloc) {
leafAllocMapper.create(leafAlloc);
return ResponseEntity.ok(leafAlloc);
}
}
CREATE TABLE `leaf_alloc` (
`biz_tag` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
`max_id` bigint(20) NOT NULL DEFAULT 1,
`step` int(11) NOT NULL,
`description` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
PRIMARY KEY (`biz_tag`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;