feat: 配置初始化
This commit is contained in:
parent
a2aad2204f
commit
06ebd5c664
|
@ -9,13 +9,43 @@
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<properties>
|
<properties>
|
||||||
|
<netty.version>4.1.115.Final</netty.version>
|
||||||
|
<protostuff.version>1.3.0</protostuff.version>
|
||||||
<hutool.version>5.8.33</hutool.version>
|
<hutool.version>5.8.33</hutool.version>
|
||||||
<configuration.version>1.10</configuration.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<artifactId>kenaito-config-core</artifactId>
|
<artifactId>kenaito-config-core</artifactId>
|
||||||
<name>子模块-配置中心sdk</name>
|
<name>子模块-配置中心sdk</name>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-all</artifactId>
|
||||||
|
<version>${netty.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- protostuff -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.dyuproject.protostuff</groupId>
|
||||||
|
<artifactId>protostuff-api</artifactId>
|
||||||
|
<version>${protostuff.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.dyuproject.protostuff</groupId>
|
||||||
|
<artifactId>protostuff-core</artifactId>
|
||||||
|
<version>${protostuff.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.dyuproject.protostuff</groupId>
|
||||||
|
<artifactId>protostuff-runtime</artifactId>
|
||||||
|
<version>${protostuff.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 工具包 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>${hutool.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
package cn.odboy.config;
|
|
||||||
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ConfigCenterClient {
|
|
||||||
|
|
||||||
private final RestTemplate restTemplate;
|
|
||||||
private final String configCenterUrl;
|
|
||||||
|
|
||||||
public ConfigCenterClient(String configCenterUrl) {
|
|
||||||
this.restTemplate = new RestTemplate();
|
|
||||||
this.configCenterUrl = configCenterUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Object> fetchConfig() {
|
|
||||||
ResponseEntity<Map> response = restTemplate.getForEntity(configCenterUrl, Map.class);
|
|
||||||
if (response.getStatusCode().is2xxSuccessful()) {
|
|
||||||
return response.getBody();
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Failed to fetch config from config center");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package cn.odboy.config;
|
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.core.env.ConfigurableEnvironment;
|
|
||||||
import org.springframework.core.env.MapPropertySource;
|
|
||||||
import java.util.Map;
|
|
||||||
/**
|
|
||||||
* 配置加载器
|
|
||||||
* @author odboy
|
|
||||||
* @date 2024-12-03
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class ConfigCenterConfigLoader {
|
|
||||||
@Bean
|
|
||||||
public BeanFactoryPostProcessor configLoader(ConfigurableEnvironment environment) {
|
|
||||||
return new BeanFactoryPostProcessor() {
|
|
||||||
@Override
|
|
||||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
|
||||||
// ConfigCenterClient client = new ConfigCenterClient("http://your-config-center-url/config");
|
|
||||||
// Map<String, Object> configKv = client.fetchConfig();
|
|
||||||
// MapPropertySource propertySource = new MapPropertySource("configCenter", configKv);
|
|
||||||
// environment.getPropertySources().addFirst(propertySource);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,7 +10,8 @@ import org.springframework.stereotype.Component;
|
||||||
@Component
|
@Component
|
||||||
@ConfigurationProperties(prefix = "kenaito.config-center")
|
@ConfigurationProperties(prefix = "kenaito.config-center")
|
||||||
public class ConfigCenterProperties {
|
public class ConfigCenterProperties {
|
||||||
private String meta;
|
private String server;
|
||||||
|
private Integer port;
|
||||||
private String dataId;
|
private String dataId;
|
||||||
private String cacheDir;
|
private String cacheDir;
|
||||||
private String env;
|
private String env;
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package cn.odboy.config.context;
|
||||||
|
|
||||||
|
import cn.odboy.config.ConfigCenterProperties;
|
||||||
|
import cn.odboy.config.netty.ConfigCenterClient;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
import org.springframework.core.env.MutablePropertySources;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置加载器
|
||||||
|
* @author odboy
|
||||||
|
* @date 2024-12-03
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Configuration
|
||||||
|
public class ConfigCenterConfigLoader {
|
||||||
|
private static final String OS_TYPE_WIN = "win";
|
||||||
|
private static final String OS_TYPE_MAC = "mac";
|
||||||
|
private static final String DEFAULT_PATH_WIN = "c:/data";
|
||||||
|
private static final String DEFAULT_PATH_MAC = "/home/admin/data";
|
||||||
|
private static final String DEFAULT_CONFIG_SERVER = "127.0.0.1";
|
||||||
|
private static final Integer DEFAULT_CONFIG_PORT = 28002;
|
||||||
|
private static final String DEFAULT_CONFIG_ENV = "default";
|
||||||
|
private static final String DEFAULT_CONFIG_DATA_ID = "default";
|
||||||
|
@Autowired
|
||||||
|
private ConfigCenterProperties properties;
|
||||||
|
@Bean
|
||||||
|
public BeanFactoryPostProcessor configLoader(ConfigurableEnvironment environment) {
|
||||||
|
return new BeanFactoryPostProcessor() {
|
||||||
|
@Override
|
||||||
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||||
|
String cacheDir;
|
||||||
|
String os = System.getProperty("os.name");
|
||||||
|
if (os.toLowerCase().startsWith(OS_TYPE_WIN)) {
|
||||||
|
cacheDir = DEFAULT_PATH_WIN;
|
||||||
|
} else if (os.toLowerCase().startsWith(OS_TYPE_MAC)) {
|
||||||
|
cacheDir = DEFAULT_PATH_MAC;
|
||||||
|
}else {
|
||||||
|
cacheDir = DEFAULT_PATH_MAC;
|
||||||
|
}
|
||||||
|
environment.getProperty("kenaito.config-center.server", String.class, DEFAULT_CONFIG_SERVER);
|
||||||
|
environment.getProperty("kenaito.config-center.port", Integer.class, DEFAULT_CONFIG_PORT);
|
||||||
|
environment.getProperty("kenaito.config-center.env", String.class, DEFAULT_CONFIG_ENV);
|
||||||
|
environment.getProperty("kenaito.config-center.data-id", String.class, DEFAULT_CONFIG_DATA_ID);
|
||||||
|
environment.getProperty("kenaito.config-center.cache-dir", String.class, cacheDir);
|
||||||
|
ConfigCenterClient client = new ConfigCenterClient();
|
||||||
|
try {
|
||||||
|
client.start(properties);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error("Netty Client Start Error", e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
// ConfigCenterClient client = new ConfigCenterClient("http://your-config-center-url/config");
|
||||||
|
// Map<String, Object> configKv = client.fetchConfig();
|
||||||
|
// MapPropertySource propertySource = new MapPropertySource("configCenter", configKv);
|
||||||
|
// environment.getPropertySources().addFirst(propertySource);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package cn.odboy.config.model;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class ConfigKv implements Serializable {
|
||||||
|
private String key;
|
||||||
|
private Object value;
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package cn.odboy.config.netty;
|
||||||
|
import cn.odboy.config.ConfigCenterProperties;
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.ChannelPipeline;
|
||||||
|
import io.netty.channel.EventLoopGroup;
|
||||||
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class ConfigCenterClient {
|
||||||
|
public void start(ConfigCenterProperties properties) throws InterruptedException {
|
||||||
|
EventLoopGroup group = new NioEventLoopGroup();
|
||||||
|
try {
|
||||||
|
Bootstrap bootstrap = new Bootstrap();
|
||||||
|
bootstrap.group(group).channel(NioSocketChannel.class)
|
||||||
|
.handler(new ChannelInitializer<SocketChannel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(SocketChannel ch) throws Exception {
|
||||||
|
ChannelPipeline pipeline = ch.pipeline();
|
||||||
|
pipeline.addLast(new ConfigCenterClientHandler());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
log.info("Netty Client Start...");
|
||||||
|
ChannelFuture channelFuture = bootstrap.connect(properties.getServer(), properties.getPort()).sync();
|
||||||
|
channelFuture.channel().closeFuture().sync();
|
||||||
|
} finally {
|
||||||
|
group.shutdownGracefully();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package cn.odboy.config.netty;
|
||||||
|
|
||||||
|
import cn.odboy.config.model.ConfigKv;
|
||||||
|
import cn.odboy.config.util.ProtostuffUtil;
|
||||||
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
public class ConfigCenterClientHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
@Override
|
||||||
|
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||||
|
System.out.println("收到服务器消息:" + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||||
|
System.out.println("MyClientHandler发送数据");
|
||||||
|
//ctx.writeAndFlush("测试String编解码");
|
||||||
|
//测试对象编解码
|
||||||
|
//ctx.writeAndFlush(new User(1,"zhuge"));
|
||||||
|
//测试用protostuff对对象编解码
|
||||||
|
ByteBuf buf = Unpooled.copiedBuffer(ProtostuffUtil.serializer(new ConfigKv("app.config", "张三")));
|
||||||
|
ctx.writeAndFlush(buf);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package cn.odboy.config.util;
|
||||||
|
|
||||||
|
import cn.odboy.config.model.ConfigKv;
|
||||||
|
import com.dyuproject.protostuff.LinkedBuffer;
|
||||||
|
import com.dyuproject.protostuff.ProtostuffIOUtil;
|
||||||
|
import com.dyuproject.protostuff.Schema;
|
||||||
|
import com.dyuproject.protostuff.runtime.RuntimeSchema;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* protostuff 序列化工具类,基于protobuf封装
|
||||||
|
*/
|
||||||
|
public class ProtostuffUtil {
|
||||||
|
|
||||||
|
private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<Class<?>, Schema<?>>();
|
||||||
|
|
||||||
|
private static <T> Schema<T> getSchema(Class<T> clazz) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Schema<T> schema = (Schema<T>) cachedSchema.get(clazz);
|
||||||
|
if (schema == null) {
|
||||||
|
schema = RuntimeSchema.getSchema(clazz);
|
||||||
|
if (schema != null) {
|
||||||
|
cachedSchema.put(clazz, schema);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 序列化
|
||||||
|
*
|
||||||
|
* @param obj
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <T> byte[] serializer(T obj) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Class<T> clazz = (Class<T>) obj.getClass();
|
||||||
|
LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
|
||||||
|
try {
|
||||||
|
Schema<T> schema = getSchema(clazz);
|
||||||
|
return ProtostuffIOUtil.toByteArray(obj, schema, buffer);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalStateException(e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 反序列化
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @param clazz
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <T> T deserializer(byte[] data, Class<T> clazz) {
|
||||||
|
try {
|
||||||
|
T obj = clazz.newInstance();
|
||||||
|
Schema<T> schema = getSchema(clazz);
|
||||||
|
ProtostuffIOUtil.mergeFrom(data, obj, schema);
|
||||||
|
return obj;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalStateException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
byte[] userBytes = ProtostuffUtil.serializer(new ConfigKv("app.config", "zhuge"));
|
||||||
|
ConfigKv user = ProtostuffUtil.deserializer(userBytes, ConfigKv.class);
|
||||||
|
System.out.println(user);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package cn.odboy.infra.netty;
|
||||||
|
|
||||||
|
import cn.hutool.core.thread.ThreadUtil;
|
||||||
|
import cn.odboy.config.ConfigCenterProperties;
|
||||||
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.ChannelPipeline;
|
||||||
|
import io.netty.channel.EventLoopGroup;
|
||||||
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class ConfigNettyServer implements InitializingBean {
|
||||||
|
@Autowired
|
||||||
|
private ConfigCenterProperties properties;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
ThreadUtil.execAsync(() -> {
|
||||||
|
try {
|
||||||
|
start();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error("Netty Server Start Error", e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() throws InterruptedException {
|
||||||
|
EventLoopGroup bossGroup = new NioEventLoopGroup(2);
|
||||||
|
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||||
|
try {
|
||||||
|
ServerBootstrap serverBootstrap = new ServerBootstrap();
|
||||||
|
serverBootstrap.group(bossGroup, workerGroup)
|
||||||
|
.channel(NioServerSocketChannel.class)
|
||||||
|
.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(SocketChannel ch) throws Exception {
|
||||||
|
ChannelPipeline pipeline = ch.pipeline();
|
||||||
|
pipeline.addLast(new ConfigServerHandler());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
log.info("Netty Server Start...");
|
||||||
|
ChannelFuture channelFuture = serverBootstrap.bind(properties.getPort()).sync();
|
||||||
|
channelFuture.channel().closeFuture().sync();
|
||||||
|
} finally {
|
||||||
|
bossGroup.shutdownGracefully();
|
||||||
|
workerGroup.shutdownGracefully();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package cn.odboy.infra.netty;
|
||||||
|
|
||||||
|
import cn.odboy.config.model.ConfigKv;
|
||||||
|
import cn.odboy.config.util.ProtostuffUtil;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
|
||||||
|
public class ConfigServerHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
@Override
|
||||||
|
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||||
|
//System.out.println("从客户端读取到String:" + msg.toString());
|
||||||
|
//System.out.println("从客户端读取到Object:" + ((User)msg).toString());
|
||||||
|
//测试用protostuff对对象编解码
|
||||||
|
ByteBuf buf = (ByteBuf) msg;
|
||||||
|
byte[] bytes = new byte[buf.readableBytes()];
|
||||||
|
buf.readBytes(bytes);
|
||||||
|
System.out.println("从客户端读取到Object:" + ProtostuffUtil.deserializer(bytes, ConfigKv.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||||
|
cause.printStackTrace();
|
||||||
|
ctx.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
kenaito:
|
kenaito:
|
||||||
config-center:
|
config-center:
|
||||||
meta: http://127.0.0.1:28002
|
server: 127.0.0.1
|
||||||
|
port: 28002
|
||||||
data-id: kenaito-config-service
|
data-id: kenaito-config-service
|
||||||
cache-dir: /home/admin/data
|
cache-dir: /home/admin/data
|
||||||
env: daily
|
env: daily
|
|
@ -1,6 +1,7 @@
|
||||||
kenaito:
|
kenaito:
|
||||||
config-center:
|
config-center:
|
||||||
meta: http://127.0.0.1:28000
|
server: 127.0.0.1
|
||||||
|
port: 28002
|
||||||
data-id: kenaito-config-service
|
data-id: kenaito-config-service
|
||||||
cache-dir: /home/admin/data
|
cache-dir: /home/admin/data
|
||||||
env: production
|
env: production
|
|
@ -1,6 +1,7 @@
|
||||||
kenaito:
|
kenaito:
|
||||||
config-center:
|
config-center:
|
||||||
meta: http://127.0.0.1:28002
|
server: 127.0.0.1
|
||||||
|
port: 28002
|
||||||
data-id: kenaito-config-service
|
data-id: kenaito-config-service
|
||||||
cache-dir: /home/admin/data
|
cache-dir: /home/admin/data
|
||||||
env: stage
|
env: stage
|
|
@ -1,4 +1,4 @@
|
||||||
spring:
|
spring:
|
||||||
profiles:
|
profiles:
|
||||||
# 激活哪个配置文件, application-{active}.yml
|
# 激活哪个配置文件, application-{active}.yml
|
||||||
active: dev
|
active: daily
|
||||||
|
|
Loading…
Reference in New Issue