nacos 服务端
nacos 服务端
服务端路径:/root/CAD_Registry_Center/nacos/nacos/bin
单机版启动脚本后,服务的启动参数:
/usr/local/jdk1.8.0_211/bin/java
-Xms512m
-Xmx512m
-Xmn256m
-Dnacos.standalone=true
-Dnacos.member.list=
-Djava.ext.dirs=/usr/local/jdk1.8.0_211/jre/lib/ext:/usr/local/jdk1.8.0_211/lib/ext
-Xloggc:/root/CAD_Registry_Center/nacos/nacos/logs/nacos_gc.log
-verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=100M
-Dloader.path=/root/CAD_Registry_Center/nacos/nacos/plugins/health,
/root/CAD_Registry_Center/nacos/nacos/plugins/cmdb,/root/CAD_Registry_Center/nacos/nacos/plugins/mysql
-Dnacos.home=/root/CAD_Registry_Center/nacos/nacos
-jar /root/CAD_Registry_Center/nacos/nacos/target/nacos-server.jar
--spring.config.location=classpath:/,classpath:/config/,file:./,file:./config/,
file:/root/CAD_Registry_Center/nacos/nacos/conf/
--logging.config=/root/CAD_Registry_Center/nacos/nacos/conf/nacos-logback.xml
--server.max-http-header-size=524288
nacos.nacos
nacos 配置中心
修改配置
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=example.properties&group=DEFAULT_GROUP&content=useLocalCache=false"
nacos 注册中心
https://nacos.io/img/nacosMap.jpg
获取服务列表
curl -GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'
注册服务
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=201.18.7.10&port=8080'
相关链接
https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html
https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html
https://nacos.io/en-us/docs/quick-start-spring-cloud.html
https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明
https://nacos.io/en-us/docs/what-is-nacos.html
https://github.com/alibaba/Nacos
https://www.cnblogs.com/songjilong/p/12796258.html
http://itmuch.com/spring-cloud/spring-cloud-index/
https://yq.aliyun.com/articles/716337
Spring 社区的唯一一个国产开源项目 - Spring Cloud Alibaba 毕业了
https://www.zhihu.com/question/289129028
https://github.com/alibaba/spring-cloud-alibab
nacos 工具代码
并发读写文件,采用lock和randomAccessFile
public class ConcurrentDiskUtil {
/**
* get file content
*
* @param path file path
* @param charsetName charsetName
* @return content
* @throws IOException IOException
*/
public static String getFileContent(String path, String charsetName)
throws IOException {
File file = new File(path);
return getFileContent(file, charsetName);
}
/**
* get file content
*
* @param file file
* @param charsetName charsetName
* @return content
* @throws IOException IOException
*/
public static String getFileContent(File file, String charsetName)
throws IOException {
RandomAccessFile fis = null;
FileLock rlock = null;
try {
fis = new RandomAccessFile(file, "r");
FileChannel fcin = fis.getChannel();
int i = 0;
do {
try {
rlock = fcin.tryLock(0L, Long.MAX_VALUE, true);
} catch (Exception e) {
++i;
if (i > RETRY_COUNT) {
NAMING_LOGGER.error("[NA] read " + file.getName() + " fail;retryed time: " + i, e);
throw new IOException("read " + file.getAbsolutePath()
+ " conflict");
}
sleep(SLEEP_BASETIME * i);
NAMING_LOGGER.warn("read " + file.getName() + " conflict;retry time: " + i);
}
} while (null == rlock);
int fileSize = (int)fcin.size();
ByteBuffer byteBuffer = ByteBuffer.allocate(fileSize);
fcin.read(byteBuffer);
byteBuffer.flip();
return byteBufferToString(byteBuffer, charsetName);
} finally {
if (rlock != null) {
rlock.release();
rlock = null;
}
if (fis != null) {
fis.close();
fis = null;
}
}
}
/**
* write file content
*
* @param path file path
* @param content content
* @param charsetName charsetName
* @return whether write ok
* @throws IOException IOException
*/
public static Boolean writeFileContent(String path, String content,
String charsetName) throws IOException {
File file = new File(path);
return writeFileContent(file, content, charsetName);
}
/**
* write file content
*
* @param file file
* @param content content
* @param charsetName charsetName
* @return whether write ok
* @throws IOException IOException
*/
public static Boolean writeFileContent(File file, String content,
String charsetName) throws IOException {
if (!file.exists() && !file.createNewFile()) {
return false;
}
FileChannel channel = null;
FileLock lock = null;
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(file, "rw");
channel = raf.getChannel();
int i = 0;
do {
try {
lock = channel.tryLock();
} catch (Exception e) {
++i;
if (i > RETRY_COUNT) {
NAMING_LOGGER.error("[NA] write {} fail;retryed time:{}", file.getName(), i);
throw new IOException("write " + file.getAbsolutePath()
+ " conflict", e);
}
sleep(SLEEP_BASETIME * i);
NAMING_LOGGER.warn("write " + file.getName() + " conflict;retry time: " + i);
}
} while (null == lock);
ByteBuffer sendBuffer = ByteBuffer.wrap(content
.getBytes(charsetName));
while (sendBuffer.hasRemaining()) {
channel.write(sendBuffer);
}
channel.truncate(content.length());
} catch (FileNotFoundException e) {
throw new IOException("file not exist");
} finally {
if (lock != null) {
try {
lock.release();
lock = null;
} catch (IOException e) {
NAMING_LOGGER.warn("close wrong", e);
}
}
if (channel != null) {
try {
channel.close();
channel = null;
} catch (IOException e) {
NAMING_LOGGER.warn("close wrong", e);
}
}
if (raf != null) {
try {
raf.close();
raf = null;
} catch (IOException e) {
NAMING_LOGGER.warn("close wrong", e);
}
}
}
return true;
}
/**
* transfer ByteBuffer to String
*
* @param buffer buffer
* @param charsetName charsetName
* @return String
* @throws IOException IOException
*/
public static String byteBufferToString(ByteBuffer buffer,
String charsetName) throws IOException {
Charset charset = null;
CharsetDecoder decoder = null;
CharBuffer charBuffer = null;
charset = Charset.forName(charsetName);
decoder = charset.newDecoder();
charBuffer = decoder.decode(buffer.asReadOnlyBuffer());
return charBuffer.toString();
}
private static void sleep(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
NAMING_LOGGER.warn("sleep wrong", e);
}
}
private static final int RETRY_COUNT = 10;
private static final int SLEEP_BASETIME = 10;
}
public static void write(ServiceInfo dom, String dir) {
try {
makeSureCacheDirExists(dir);
File file = new File(dir, dom.getKeyEncoded());
if (!file.exists()) {
// add another !file.exists() to avoid conflicted creating-new-file from multi-instances
if (!file.createNewFile() && !file.exists()) {
throw new IllegalStateException("failed to create cache file");
}
}
StringBuilder keyContentBuffer = new StringBuilder("");
String json = dom.getJsonFromServer();
if (StringUtils.isEmpty(json)) {
json = JSON.toJSONString(dom);
}
keyContentBuffer.append(json);
//Use the concurrent API to ensure the consistency.
ConcurrentDiskUtil.writeFileContent(file, keyContentBuffer.toString(), Charset.defaultCharset().toString());
} catch (Throwable e) {
NAMING_LOGGER.error("[NA] failed to write cache for dom:" + dom.getName(), e);
}
}
public static String getLineSeparator() {
return System.getProperty("line.separator");
}
public static Map<String, ServiceInfo> read(String cacheDir) {
Map<String, ServiceInfo> domMap = new HashMap<String, ServiceInfo>(16);
BufferedReader reader = null;
try {
File[] files = makeSureCacheDirExists(cacheDir).listFiles();
if (files == null || files.length == 0) {
return domMap;
}
for (File file : files) {
if (!file.isFile()) {
continue;
}
String fileName = URLDecoder.decode(file.getName(), "UTF-8");
if (!(fileName.endsWith(Constants.SERVICE_INFO_SPLITER + "meta") || fileName.endsWith(
Constants.SERVICE_INFO_SPLITER + "special-url"))) {
ServiceInfo dom = new ServiceInfo(fileName);
List<Instance> ips = new ArrayList<Instance>();
dom.setHosts(ips);
ServiceInfo newFormat = null;
try {
String dataString = ConcurrentDiskUtil.getFileContent(file,
Charset.defaultCharset().toString());
reader = new BufferedReader(new StringReader(dataString));
String json;
while ((json = reader.readLine()) != null) {
try {
if (!json.startsWith("{")) {
continue;
}
newFormat = JSON.parseObject(json, ServiceInfo.class);
if (StringUtils.isEmpty(newFormat.getName())) {
ips.add(JSON.parseObject(json, Instance.class));
}
} catch (Throwable e) {
NAMING_LOGGER.error("[NA] error while parsing cache file: " + json, e);
}
}
} catch (Exception e) {
NAMING_LOGGER.error("[NA] failed to read cache for dom: " + file.getName(), e);
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (Exception e) {
//ignore
}
}
if (newFormat != null && !StringUtils.isEmpty(newFormat.getName()) && !CollectionUtils.isEmpty(
newFormat.getHosts())) {
domMap.put(dom.getKey(), newFormat);
} else if (!CollectionUtils.isEmpty(dom.getHosts())) {
domMap.put(dom.getKey(), dom);
}
}
}
} catch (Throwable e) {
NAMING_LOGGER.error("[NA] failed to read cache file", e);
}
return domMap;
}
private static File makeSureCacheDirExists(String dir) {
File cacheDir = new File(dir);
if (!cacheDir.exists()) {
if (!cacheDir.mkdirs() && !cacheDir.exists()) {
throw new IllegalStateException("failed to create cache dir: " + dir);
}
}
return cacheDir;
}
}