feat: 配置初始化
This commit is contained in:
parent
a2aad2204f
commit
06ebd5c664
|
@ -9,13 +9,43 @@
|
|||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<properties>
|
||||
<netty.version>4.1.115.Final</netty.version>
|
||||
<protostuff.version>1.3.0</protostuff.version>
|
||||
<hutool.version>5.8.33</hutool.version>
|
||||
<configuration.version>1.10</configuration.version>
|
||||
</properties>
|
||||
|
||||
<artifactId>kenaito-config-core</artifactId>
|
||||
<name>子模块-配置中心sdk</name>
|
||||
|
||||
<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>
|
||||
</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
|
||||
@ConfigurationProperties(prefix = "kenaito.config-center")
|
||||
public class ConfigCenterProperties {
|
||||
private String meta;
|
||||
private String server;
|
||||
private Integer port;
|
||||
private String dataId;
|
||||
private String cacheDir;
|
||||
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:
|
||||
config-center:
|
||||
meta: http://127.0.0.1:28002
|
||||
server: 127.0.0.1
|
||||
port: 28002
|
||||
data-id: kenaito-config-service
|
||||
cache-dir: /home/admin/data
|
||||
env: daily
|
|
@ -1,6 +1,7 @@
|
|||
kenaito:
|
||||
config-center:
|
||||
meta: http://127.0.0.1:28000
|
||||
server: 127.0.0.1
|
||||
port: 28002
|
||||
data-id: kenaito-config-service
|
||||
cache-dir: /home/admin/data
|
||||
env: production
|
|
@ -1,6 +1,7 @@
|
|||
kenaito:
|
||||
config-center:
|
||||
meta: http://127.0.0.1:28002
|
||||
server: 127.0.0.1
|
||||
port: 28002
|
||||
data-id: kenaito-config-service
|
||||
cache-dir: /home/admin/data
|
||||
env: stage
|
|
@ -1,4 +1,4 @@
|
|||
spring:
|
||||
profiles:
|
||||
# 激活哪个配置文件, application-{active}.yml
|
||||
active: dev
|
||||
active: daily
|
||||
|
|
Loading…
Reference in New Issue