Merge branch 'develop' into master

This commit is contained in:
mingyixu 2019-01-15 17:00:43 +08:00 committed by GitHub
commit a689f0f694
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
230 changed files with 8959 additions and 6277 deletions

2
.gitignore vendored
View File

@ -5,7 +5,9 @@
target target
.project .project
.idea .idea
.vscode
.DS_Store .DS_Store
.factorypath
/logs /logs
*.iml *.iml
node_modules node_modules

View File

@ -16,7 +16,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>0.7.0</version> <version>0.8.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -31,7 +31,7 @@ import com.alibaba.nacos.api.naming.NamingService;
public class NacosFactory { public class NacosFactory {
/** /**
* Create config * Create config service
* *
* @param properties init param * @param properties init param
* @return config * @return config
@ -42,7 +42,7 @@ public class NacosFactory {
} }
/** /**
* Create config * Create config service
* *
* @param serverAddr server list * @param serverAddr server list
* @return config * @return config
@ -53,7 +53,7 @@ public class NacosFactory {
} }
/** /**
* Create Naming * Create naming service
* *
* @param serverAddr server list * @param serverAddr server list
* @return Naming * @return Naming
@ -64,7 +64,7 @@ public class NacosFactory {
} }
/** /**
* Create Naming * Create naming service
* *
* @param properties init param * @param properties init param
* @return Naming * @return Naming

View File

@ -16,20 +16,30 @@
package com.alibaba.nacos.api; package com.alibaba.nacos.api;
/** /**
* properties key * Property Key Const
* *
* @author Nacos * @author Nacos
*/ */
public class PropertyKeyConst { public class PropertyKeyConst {
public final static String ENDPOINT = "endpoint"; public final static String ENDPOINT = "endpoint";
public final static String NAMESPACE = "namespace"; public final static String NAMESPACE = "namespace";
public final static String ACCESS_KEY = "accessKey"; public final static String ACCESS_KEY = "accessKey";
public final static String SECRET_KEY = "secretKey"; public final static String SECRET_KEY = "secretKey";
public final static String SERVER_ADDR = "serverAddr"; public final static String SERVER_ADDR = "serverAddr";
public final static String CONTEXT_PATH = "contextPath"; public final static String CONTEXT_PATH = "contextPath";
public final static String CLUSTER_NAME = "clusterName"; public final static String CLUSTER_NAME = "clusterName";
public final static String ENCODE = "encode"; public final static String ENCODE = "encode";
public final static String NAMING_LOAD_CACHE_AT_START = "namingLoadCacheAtStart"; public final static String NAMING_LOAD_CACHE_AT_START = "namingLoadCacheAtStart";
public final static String NAMING_CLIENT_BEAT_THREAD_COUNT = "namingClientBeatThreadCount";
public final static String NAMING_POLLING_THREAD_COUNT = "namingPollingThreadCount";
} }

View File

@ -19,6 +19,7 @@ import java.util.Map;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public class Entity { public class Entity {

View File

@ -17,6 +17,7 @@ package com.alibaba.nacos.api.cmdb.pojo;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public class EntityEvent { public class EntityEvent {

View File

@ -17,6 +17,7 @@ package com.alibaba.nacos.api.cmdb.pojo;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public enum EntityEventType { public enum EntityEventType {
/** /**

View File

@ -19,6 +19,7 @@ import java.util.Set;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public class Label { public class Label {

View File

@ -17,14 +17,15 @@ package com.alibaba.nacos.api.cmdb.pojo;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public enum PreservedEntityTypes { public enum PreservedEntityTypes {
/** /**
* * Ip
*/ */
ip, ip,
/** /**
* * Service
*/ */
service service
} }

View File

@ -27,6 +27,7 @@ import java.util.Set;
* Service to visit CMDB store * Service to visit CMDB store
* *
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public interface CmdbService { public interface CmdbService {

View File

@ -85,11 +85,6 @@ public class Constants {
*/ */
public static final int ONCE_TIMEOUT = 2000; public static final int ONCE_TIMEOUT = 2000;
/**
* millisecond
*/
public static final int CONN_TIMEOUT = 2000;
/** /**
* millisecond * millisecond
*/ */
@ -114,7 +109,7 @@ public class Constants {
public static final String WORD_SEPARATOR = Character.toString((char)2); public static final String WORD_SEPARATOR = Character.toString((char)2);
public static final String LONGPULLING_LINE_SEPARATOR = "\r\n"; public static final String LONGPOLLING_LINE_SEPARATOR = "\r\n";
public static final String CLIENT_APPNAME_HEADER = "Client-AppName"; public static final String CLIENT_APPNAME_HEADER = "Client-AppName";
public static final String CLIENT_REQUEST_TS_HEADER = "Client-RequestTS"; public static final String CLIENT_REQUEST_TS_HEADER = "Client-RequestTS";
@ -127,4 +122,10 @@ public class Constants {
public static final String NAMING_HTTP_HEADER_SPILIER = "\\|"; public static final String NAMING_HTTP_HEADER_SPILIER = "\\|";
public static final String NAMING_DEFAULT_CLUSTER_NAME = "DEFAULT"; public static final String NAMING_DEFAULT_CLUSTER_NAME = "DEFAULT";
public static final String REQUEST_PARAM_NAMESPACE_ID = "namespaceId";
public static final String REQUEST_PARAM_DEFAULT_NAMESPACE_ID = "public";
public static final String REQUEST_PARAM_SERVICE_NAME = "serviceName";
public static final String REQUEST_PARAM_GROUP = "group";
public static final String REQUEST_PARAM_DEFAULT_GROUP = "DEFAULT_GROUP";
} }

View File

@ -32,7 +32,7 @@ public class ConfigFactory {
* Create Config * Create Config
* *
* @param properties init param * @param properties init param
* @return Config * @return ConfigService
* @throws NacosException Exception * @throws NacosException Exception
*/ */
public static ConfigService createConfigService(Properties properties) throws NacosException { public static ConfigService createConfigService(Properties properties) throws NacosException {
@ -49,21 +49,14 @@ public class ConfigFactory {
/** /**
* Create Config * Create Config
* *
* @param ServerAddr serverlist * @param serverAddr serverList
* @return Config * @return Config
* @throws NacosException Exception * @throws ConfigService Exception
*/ */
public static ConfigService createConfigService(String serverAddr) throws NacosException { public static ConfigService createConfigService(String serverAddr) throws NacosException {
Properties properties = new Properties(); Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr); properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
try { return createConfigService(properties);
Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.config.NacosConfigService");
Constructor constructor = driverImplClass.getConstructor(Properties.class);
ConfigService vendorImpl = (ConfigService)constructor.newInstance(properties);
return vendorImpl;
} catch (Throwable e) {
throw new NacosException(-400, e.getMessage());
}
} }
} }

View File

@ -19,17 +19,17 @@ import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
/** /**
* Config Interface * Config Service Interface
* *
* @author Nacos * @author Nacos
*/ */
public interface ConfigService { public interface ConfigService {
/** /**
* Get Configuration * Get config
* *
* @param dataId Config ID * @param dataId dataId
* @param group Config Group * @param group group
* @param timeoutMs read timeout * @param timeoutMs read timeout
* @return config value * @return config value
* @throws NacosException NacosException * @throws NacosException NacosException
@ -37,50 +37,52 @@ public interface ConfigService {
String getConfig(String dataId, String group, long timeoutMs) throws NacosException; String getConfig(String dataId, String group, long timeoutMs) throws NacosException;
/** /**
* Add a listener to the configuration, after the server to modify the configuration, the client will use the * Add a listener to the configuration, after the server modified the
* incoming listener callback. Recommended asynchronous processing, the application can implement the getExecutor * configuration, the client will use the incoming listener callback.
* method in the ManagerListener, provide a thread pool of execution. If provided, use the main thread callback, May * Recommended asynchronous processing, the application can implement the
* block other configurations or be blocked by other configurations. * getExecutor method in the ManagerListener, provide a thread pool of
* execution. If provided, use the main thread callback, May block other
* configurations or be blocked by other configurations.
* *
* @param dataId Config ID * @param dataId dataId
* @param group Config Group * @param group group
* @param listener listener * @param listener listener
* @throws NacosException NacosException * @throws NacosException NacosException
*/ */
void addListener(String dataId, String group, Listener listener) throws NacosException; void addListener(String dataId, String group, Listener listener) throws NacosException;
/** /**
* publish config. * Publish config.
* *
* @param dataId Config ID * @param dataId dataId
* @param group Config Group * @param group group
* @param content Config Content * @param content content
* @return Whether publish * @return Whether publish
* @throws NacosException NacosException * @throws NacosException NacosException
*/ */
boolean publishConfig(String dataId, String group, String content) throws NacosException; boolean publishConfig(String dataId, String group, String content) throws NacosException;
/** /**
* Remove Config * Remove config
* *
* @param dataId Config ID * @param dataId dataId
* @param group Config Group * @param group group
* @return whether remove * @return whether remove
* @throws NacosException NacosException * @throws NacosException NacosException
*/ */
boolean removeConfig(String dataId, String group) throws NacosException; boolean removeConfig(String dataId, String group) throws NacosException;
/** /**
* Remove Listener * Remove listener
* *
* @param dataId Config ID * @param dataId dataId
* @param group Config Group * @param group group
* @param listener listener * @param listener listener
*/ */
void removeListener(String dataId, String group, Listener listener); void removeListener(String dataId, String group, Listener listener);
/** /**
* server health info * Get server status
* *
* @return whether health * @return whether health
*/ */

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.api.config.convert; package com.alibaba.nacos.api.config.convert;
/** /**
* Nacos Configuration content Converter * Nacos Config Converter
* *
* @param <T> the target type that wanted * @param <T> the target type that wanted
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a> * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
@ -25,7 +25,7 @@ package com.alibaba.nacos.api.config.convert;
public interface NacosConfigConverter<T> { public interface NacosConfigConverter<T> {
/** /**
* Can convert to be target type or not * can convert to be target type or not
* *
* @param targetType the type of target * @param targetType the type of target
* @return If can , return <code>true</code>, or <code>false</code> * @return If can , return <code>true</code>, or <code>false</code>
@ -33,9 +33,9 @@ public interface NacosConfigConverter<T> {
boolean canConvert(Class<T> targetType); boolean canConvert(Class<T> targetType);
/** /**
* Convert the Naocs's configuration of type S to target type T. * convert the Naocs's config of type S to target type T.
* *
* @param config the Naocs's configuration to convert, which must be an instance of S (never {@code null}) * @param config the Naocs's config to convert, which must be an instance of S (never {@code null})
* @return the converted object, which must be an instance of T (potentially {@code null}) * @return the converted object, which must be an instance of T (potentially {@code null})
*/ */
T convert(String config); T convert(String config);

View File

@ -22,18 +22,18 @@ package com.alibaba.nacos.api.config.filter;
*/ */
public interface IConfigContext { public interface IConfigContext {
/** /**
* get context by key * Get context param by key
* *
* @param key * @param key
* @return context * @return context
*/ */
public Object getParameter(String key); Object getParameter(String key);
/** /**
* set context * Set context param
* *
* @param key key * @param key key
* @param value value * @param value value
*/ */
public void setParameter(String key, Object value); void setParameter(String key, Object value);
} }

View File

@ -24,7 +24,7 @@ import com.alibaba.nacos.api.exception.NacosException;
*/ */
public interface IConfigFilter { public interface IConfigFilter {
/** /**
* Init Fuction * Init
* *
* @param filterConfig Filter Config * @param filterConfig Filter Config
*/ */
@ -47,16 +47,16 @@ public interface IConfigFilter {
void deploy(); void deploy();
/** /**
* order * Get order
* *
* @return * @return order number
*/ */
int getOrder(); int getOrder();
/** /**
* filterName * Get filterName
* *
* @return * @return filter name
*/ */
String getFilterName(); String getFilterName();

View File

@ -30,6 +30,6 @@ public interface IConfigFilterChain {
* @param response response * @param response response
* @throws NacosException NacosException * @throws NacosException NacosException
*/ */
public void doFilter(IConfigRequest request, IConfigResponse response) throws NacosException; void doFilter(IConfigRequest request, IConfigResponse response) throws NacosException;
} }

View File

@ -27,13 +27,13 @@ public interface IConfigRequest {
* @param key key * @param key key
* @return value * @return value
*/ */
public Object getParameter(String key); Object getParameter(String key);
/** /**
* get config context * get config context
* *
* @return * @return
*/ */
public IConfigContext getConfigContext(); IConfigContext getConfigContext();
} }

View File

@ -27,13 +27,13 @@ public interface IConfigResponse {
* @param key key * @param key key
* @return value * @return value
*/ */
public Object getParameter(String key); Object getParameter(String key);
/** /**
* get context * Get config context
* *
* @return configContext * @return configContext
*/ */
public IConfigContext getConfigContext(); IConfigContext getConfigContext();
} }

View File

@ -27,14 +27,14 @@ public interface IFilterConfig {
* *
* @return * @return
*/ */
public String getFilterName(); String getFilterName();
/** /**
* get param * Get init param
* *
* @param name * @param name
* @return param * @return param
*/ */
public Object getInitParameter(String name); Object getInitParameter(String name);
} }

View File

@ -26,8 +26,9 @@ import java.util.concurrent.Executor;
public abstract class AbstractListener implements Listener { public abstract class AbstractListener implements Listener {
/** /**
* use default Executor * Use default executor
*/ */
@Override
public Executor getExecutor() { public Executor getExecutor() {
return null; return null;
} }

View File

@ -18,7 +18,7 @@ package com.alibaba.nacos.api.config.listener;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
/** /**
* shared listener * Shared Listener
* *
* @author Nacos * @author Nacos
*/ */

View File

@ -25,16 +25,16 @@ import java.util.concurrent.Executor;
public interface Listener { public interface Listener {
/** /**
* Executor to excute this receive * Get executor for execute this receive
* *
* @return Executor * @return Executor
*/ */
public Executor getExecutor(); Executor getExecutor();
/** /**
* 接收配置信息 * Receive config info
* *
* @param configInfo 配置值 * @param configInfo config info
*/ */
public void receiveConfigInfo(final String configInfo); void receiveConfigInfo(final String configInfo);
} }

View File

@ -21,7 +21,9 @@ import java.util.Properties;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * Naming Factory
*
* @author dungu.zpf
*/ */
public class NamingFactory { public class NamingFactory {

View File

@ -25,12 +25,14 @@ import com.alibaba.nacos.api.selector.AbstractSelector;
import java.util.List; import java.util.List;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * Naming Service
*
* @author dungu.zpf
*/ */
public interface NamingService { public interface NamingService {
/** /**
* Register a instance to service * register a instance to service
* *
* @param serviceName name of service * @param serviceName name of service
* @param ip instance ip * @param ip instance ip
@ -40,7 +42,7 @@ public interface NamingService {
void registerInstance(String serviceName, String ip, int port) throws NacosException; void registerInstance(String serviceName, String ip, int port) throws NacosException;
/** /**
* Register a instance to service with specified cluster name * register a instance to service with specified cluster name
* *
* @param serviceName name of service * @param serviceName name of service
* @param ip instance ip * @param ip instance ip
@ -51,7 +53,7 @@ public interface NamingService {
void registerInstance(String serviceName, String ip, int port, String clusterName) throws NacosException; void registerInstance(String serviceName, String ip, int port, String clusterName) throws NacosException;
/** /**
* Register a instance to service with specified instance properties * register a instance to service with specified instance properties
* *
* @param serviceName name of service * @param serviceName name of service
* @param instance instance to register * @param instance instance to register
@ -60,7 +62,7 @@ public interface NamingService {
void registerInstance(String serviceName, Instance instance) throws NacosException; void registerInstance(String serviceName, Instance instance) throws NacosException;
/** /**
* Deregister instance from a service * deregister instance from a service
* *
* @param serviceName name of service * @param serviceName name of service
* @param ip instance ip * @param ip instance ip
@ -70,7 +72,7 @@ public interface NamingService {
void deregisterInstance(String serviceName, String ip, int port) throws NacosException; void deregisterInstance(String serviceName, String ip, int port) throws NacosException;
/** /**
* Deregister instance with specified cluster name from a service * deregister instance with specified cluster name from a service
* *
* @param serviceName name of service * @param serviceName name of service
* @param ip instance ip * @param ip instance ip
@ -81,7 +83,7 @@ public interface NamingService {
void deregisterInstance(String serviceName, String ip, int port, String clusterName) throws NacosException; void deregisterInstance(String serviceName, String ip, int port, String clusterName) throws NacosException;
/** /**
* Get all instances of a service * get all instances of a service
* *
* @param serviceName name of service * @param serviceName name of service
* @return A list of instance * @return A list of instance
@ -89,6 +91,16 @@ public interface NamingService {
*/ */
List<Instance> getAllInstances(String serviceName) throws NacosException; List<Instance> getAllInstances(String serviceName) throws NacosException;
/**
* Get all instances of a service
*
* @param serviceName name of service
* @param subscribe if subscribe the service
* @return A list of instance
* @throws NacosException
*/
List<Instance> getAllInstances(String serviceName, boolean subscribe) throws NacosException;
/** /**
* Get all instances within specified clusters of a service * Get all instances within specified clusters of a service
* *
@ -99,6 +111,17 @@ public interface NamingService {
*/ */
List<Instance> getAllInstances(String serviceName, List<String> clusters) throws NacosException; List<Instance> getAllInstances(String serviceName, List<String> clusters) throws NacosException;
/**
* Get all instances within specified clusters of a service
*
* @param serviceName name of service
* @param clusters list of cluster
* @param subscribe if subscribe the service
* @return A list of qualified instance
* @throws NacosException
*/
List<Instance> getAllInstances(String serviceName, List<String> clusters, boolean subscribe) throws NacosException;
/** /**
* Get qualified instances of service * Get qualified instances of service
* *
@ -109,6 +132,17 @@ public interface NamingService {
*/ */
List<Instance> selectInstances(String serviceName, boolean healthy) throws NacosException; List<Instance> selectInstances(String serviceName, boolean healthy) throws NacosException;
/**
* Get qualified instances of service
*
* @param serviceName name of service
* @param healthy a flag to indicate returning healthy or unhealthy instances
* @param subscribe if subscribe the service
* @return A qualified list of instance
* @throws NacosException
*/
List<Instance> selectInstances(String serviceName, boolean healthy, boolean subscribe) throws NacosException;
/** /**
* Get qualified instances within specified clusters of service * Get qualified instances within specified clusters of service
* *
@ -120,6 +154,18 @@ public interface NamingService {
*/ */
List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy) throws NacosException; List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy) throws NacosException;
/**
* Get qualified instances within specified clusters of service
*
* @param serviceName name of service
* @param clusters list of cluster
* @param healthy a flag to indicate returning healthy or unhealthy instances
* @param subscribe if subscribe the service
* @return A qualified list of instance
* @throws NacosException
*/
List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy, boolean subscribe) throws NacosException;
/** /**
* Select one healthy instance of service using predefined load balance strategy * Select one healthy instance of service using predefined load balance strategy
* *
@ -129,6 +175,16 @@ public interface NamingService {
*/ */
Instance selectOneHealthyInstance(String serviceName) throws NacosException; Instance selectOneHealthyInstance(String serviceName) throws NacosException;
/**
* select one healthy instance of service using predefined load balance strategy
*
* @param serviceName name of service
* @param subscribe if subscribe the service
* @return qualified instance
* @throws NacosException
*/
Instance selectOneHealthyInstance(String serviceName, boolean subscribe) throws NacosException;
/** /**
* Select one healthy instance of service using predefined load balance strategy * Select one healthy instance of service using predefined load balance strategy
* *
@ -139,6 +195,17 @@ public interface NamingService {
*/ */
Instance selectOneHealthyInstance(String serviceName, List<String> clusters) throws NacosException; Instance selectOneHealthyInstance(String serviceName, List<String> clusters) throws NacosException;
/**
* Select one healthy instance of service using predefined load balance strategy
*
* @param serviceName name of service
* @param clusters a list of clusters should the instance belongs to
* @param subscribe if subscribe the service
* @return qualified instance
* @throws NacosException
*/
Instance selectOneHealthyInstance(String serviceName, List<String> clusters, boolean subscribe) throws NacosException;
/** /**
* Subscribe service to receive events of instances alteration * Subscribe service to receive events of instances alteration
* *
@ -149,7 +216,7 @@ public interface NamingService {
void subscribe(String serviceName, EventListener listener) throws NacosException; void subscribe(String serviceName, EventListener listener) throws NacosException;
/** /**
* Subscribe service to receive events of instances alteration * subscribe service to receive events of instances alteration
* *
* @param serviceName name of service * @param serviceName name of service
* @param clusters list of cluster * @param clusters list of cluster
@ -159,7 +226,7 @@ public interface NamingService {
void subscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException; void subscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException;
/** /**
* Unsubscribe event listener of service * unsubscribe event listener of service
* *
* @param serviceName name of service * @param serviceName name of service
* @param listener event listener * @param listener event listener
@ -168,7 +235,7 @@ public interface NamingService {
void unsubscribe(String serviceName, EventListener listener) throws NacosException; void unsubscribe(String serviceName, EventListener listener) throws NacosException;
/** /**
* Unsubscribe event listener of service * unsubscribe event listener of service
* *
* @param serviceName name of service * @param serviceName name of service
* @param clusters list of cluster * @param clusters list of cluster
@ -178,7 +245,7 @@ public interface NamingService {
void unsubscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException; void unsubscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException;
/** /**
* Get all service names from server * get all service names from server
* *
* @param pageNo page index * @param pageNo page index
* @param pageSize page size * @param pageSize page size
@ -188,13 +255,14 @@ public interface NamingService {
ListView<String> getServicesOfServer(int pageNo, int pageSize) throws NacosException; ListView<String> getServicesOfServer(int pageNo, int pageSize) throws NacosException;
/** /**
* Get all service names from server * Get all subscribed services of current client
* *
* @param pageNo page index * @param pageNo page index
* @param pageSize page size * @param pageSize page size
* @param selector selector to filter the resource * @param selector selector to filter the resource
* @return list of service names * @return list of service names
* @throws NacosException * @throws NacosException
* @since 0.7.0
*/ */
ListView<String> getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector) throws NacosException; ListView<String> getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector) throws NacosException;
@ -207,7 +275,7 @@ public interface NamingService {
List<ServiceInfo> getSubscribeServices() throws NacosException; List<ServiceInfo> getSubscribeServices() throws NacosException;
/** /**
* Get server health status * get server health status
* *
* @return is server healthy * @return is server healthy
*/ */

View File

@ -16,8 +16,9 @@
package com.alibaba.nacos.api.naming.listener; package com.alibaba.nacos.api.naming.listener;
/** /**
* event interface * Event Interface
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> *
* @author dungu.zpf
*/ */
public interface Event { public interface Event {
} }

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.api.naming.listener; package com.alibaba.nacos.api.naming.listener;
/** /**
* event listener * Event Listener
* *
* @author Nacos * @author Nacos
*/ */

View File

@ -20,7 +20,9 @@ import java.util.List;
import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.Instance;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * Naming Event
*
* @author dungu.zpf
*/ */
public class NamingEvent implements Event { public class NamingEvent implements Event {

View File

@ -19,7 +19,9 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * Cluster
*
* @author dungu.zpf
*/ */
public class Cluster { public class Cluster {

View File

@ -22,32 +22,34 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * Instance
*
* @author dungu.zpf
*/ */
public class Instance { public class Instance {
/** /**
* Unique ID of this instance. * unique id of this instance.
*/ */
private String instanceId; private String instanceId;
/** /**
* Instance ip * instance ip
*/ */
private String ip; private String ip;
/** /**
* Instance port * instance port
*/ */
private int port; private int port;
/** /**
* Instance weight * instance weight
*/ */
private double weight = 1.0D; private double weight = 1.0D;
/** /**
* Instance health status * instance health status
*/ */
@JSONField(name = "valid") @JSONField(name = "valid")
private boolean healthy = true; private boolean healthy = true;
@ -55,17 +57,17 @@ public class Instance {
private boolean enabled = true; private boolean enabled = true;
/** /**
* Cluster information of instance * cluster information of instance
*/ */
private String clusterName; private String clusterName;
/** /**
* Service name of instance * Service information of instance
*/ */
private String serviceName; private String serviceName;
/** /**
* User extended attributes * user extended attributes
*/ */
private Map<String, String> metadata = new HashMap<String, String>(); private Map<String, String> metadata = new HashMap<String, String>();

View File

@ -20,7 +20,9 @@ import com.alibaba.fastjson.JSON;
import java.util.List; import java.util.List;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * ListView
*
* @author dungu.zpf
*/ */
public class ListView<T> { public class ListView<T> {

View File

@ -21,32 +21,34 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * Service
*
* @author dungu.zpf
*/ */
public class Service { public class Service {
/** /**
* Service name * service name
*/ */
private String name; private String name;
/** /**
* Protect threshold * protect threshold
*/ */
private float protectThreshold = 0.0F; private float protectThreshold = 0.0F;
/** /**
* Application name of this service * application name of this service
*/ */
private String app; private String app;
/** /**
* Service group is meant to classify services into different sets * Service group which is meant to classify services into different sets.
*/ */
private String group; private String group;
/** /**
* Health check mode * Health check mode.
*/ */
private String healthCheckMode; private String healthCheckMode;

View File

@ -24,7 +24,9 @@ import java.util.Collection;
import java.util.List; import java.util.List;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * ServiceInfo
*
* @author dungu.zpf
*/ */
public class ServiceInfo { public class ServiceInfo {
@ -46,8 +48,6 @@ public class ServiceInfo {
private String checksum = ""; private String checksum = "";
private String env = "";
private volatile boolean allIPs = false; private volatile boolean allIPs = false;
public ServiceInfo() { public ServiceInfo() {
@ -63,48 +63,22 @@ public class ServiceInfo {
public ServiceInfo(String key) { public ServiceInfo(String key) {
int maxKeySectionCount = 4; int maxIndex = 2;
int allIpFlagIndex = 3;
int envIndex = 2;
int clusterIndex = 1; int clusterIndex = 1;
int serviceNameIndex = 0; int serviceNameIndex = 0;
String[] keys = key.split(SPLITER); String[] keys = key.split(SPLITER);
if (keys.length >= maxKeySectionCount) { if (keys.length >= maxIndex) {
this.name = keys[serviceNameIndex]; this.name = keys[serviceNameIndex];
this.clusters = keys[clusterIndex]; this.clusters = keys[clusterIndex];
this.env = keys[envIndex];
if (strEquals(keys[allIpFlagIndex], ALL_IPS)) {
this.setAllIPs(true);
}
} else if (keys.length >= allIpFlagIndex) {
this.name = keys[serviceNameIndex];
this.clusters = keys[clusterIndex];
if (strEquals(keys[envIndex], ALL_IPS)) {
this.setAllIPs(true);
} else {
this.env = keys[envIndex];
}
} else if (keys.length >= envIndex) {
this.name = keys[serviceNameIndex];
if (strEquals(keys[clusterIndex], ALL_IPS)) {
this.setAllIPs(true);
} else {
this.clusters = keys[clusterIndex];
}
} }
this.name = keys[0]; this.name = keys[0];
} }
public ServiceInfo(String name, String clusters) { public ServiceInfo(String name, String clusters) {
this(name, clusters, EMPTY);
}
public ServiceInfo(String name, String clusters, String env) {
this.name = name; this.name = name;
this.clusters = clusters; this.clusters = clusters;
this.env = env;
} }
public int ipCount() { public int ipCount() {
@ -156,7 +130,6 @@ public class ServiceInfo {
} }
public List<Instance> getHosts() { public List<Instance> getHosts() {
return new ArrayList<Instance>(hosts); return new ArrayList<Instance>(hosts);
} }
@ -190,45 +163,39 @@ public class ServiceInfo {
@JSONField(serialize = false) @JSONField(serialize = false)
public String getKey() { public String getKey() {
return getKey(name, clusters, env, isAllIPs()); return getKey(name, clusters);
} }
@JSONField(serialize = false) @JSONField(serialize = false)
public String getKeyEncoded() { public String getKeyEncoded() {
try { try {
return getKey(URLEncoder.encode(name, "UTF-8"), clusters, env, isAllIPs()); return getKey(URLEncoder.encode(name, "UTF-8"), clusters);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
return getKey(); return getKey();
} }
} }
@JSONField(serialize = false) @JSONField(serialize = false)
public static String getKey(String name, String clusters, String unit) { public static ServiceInfo fromKey(String key) {
return getKey(name, clusters, unit, false); ServiceInfo serviceInfo = new ServiceInfo();
if (key.contains(SPLITER)) {
serviceInfo.setName(key.split(SPLITER)[0]);
serviceInfo.setClusters(key.split(SPLITER)[1]);
return serviceInfo;
}
serviceInfo.setName(key);
return serviceInfo;
} }
@JSONField(serialize = false) @JSONField(serialize = false)
public static String getKey(String name, String clusters, String unit, boolean isAllIPs) { public static String getKey(String name, String clusters) {
if (isEmpty(unit)) {
unit = EMPTY;
}
if (!isEmpty(clusters) && !isEmpty(unit)) {
return isAllIPs ? name + SPLITER + clusters + SPLITER + unit + SPLITER + ALL_IPS
: name + SPLITER + clusters + SPLITER + unit;
}
if (!isEmpty(clusters)) { if (!isEmpty(clusters)) {
return isAllIPs ? name + SPLITER + clusters + SPLITER + ALL_IPS : name + SPLITER + clusters; return name + SPLITER + clusters;
} }
if (!isEmpty(unit)) { return name;
return isAllIPs ? name + SPLITER + EMPTY + SPLITER + unit + SPLITER + ALL_IPS :
name + SPLITER + EMPTY + SPLITER + unit;
}
return isAllIPs ? name + SPLITER + ALL_IPS : name;
} }
@Override @Override

View File

@ -19,6 +19,7 @@ package com.alibaba.nacos.api.selector;
* Abstract selector that only contains a type * Abstract selector that only contains a type
* *
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public abstract class AbstractSelector { public abstract class AbstractSelector {

View File

@ -19,6 +19,7 @@ package com.alibaba.nacos.api.selector;
* The selector to filter resource with flexible expression. * The selector to filter resource with flexible expression.
* *
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public class ExpressionSelector extends AbstractSelector { public class ExpressionSelector extends AbstractSelector {

View File

@ -19,6 +19,7 @@ package com.alibaba.nacos.api.selector;
* The types of selector accepted by Nacos * The types of selector accepted by Nacos
* *
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public enum SelectorType { public enum SelectorType {
/** /**

View File

@ -16,7 +16,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>0.7.0</version> <version>0.8.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
@ -107,5 +107,10 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -23,10 +23,12 @@ import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager; import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
import com.alibaba.nacos.client.config.filter.impl.ConfigRequest; import com.alibaba.nacos.client.config.filter.impl.ConfigRequest;
import com.alibaba.nacos.client.config.filter.impl.ConfigResponse; import com.alibaba.nacos.client.config.filter.impl.ConfigResponse;
import com.alibaba.nacos.client.config.http.HttpAgent;
import com.alibaba.nacos.client.config.http.MetricsHttpAgent;
import com.alibaba.nacos.client.config.http.ServerHttpAgent;
import com.alibaba.nacos.client.config.impl.ClientWorker; import com.alibaba.nacos.client.config.impl.ClientWorker;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult; import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor; import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor;
import com.alibaba.nacos.client.config.impl.ServerHttpAgent;
import com.alibaba.nacos.client.config.utils.ContentUtils; import com.alibaba.nacos.client.config.utils.ContentUtils;
import com.alibaba.nacos.client.config.utils.LogUtils; import com.alibaba.nacos.client.config.utils.LogUtils;
import com.alibaba.nacos.client.config.utils.ParamUtils; import com.alibaba.nacos.client.config.utils.ParamUtils;
@ -55,9 +57,9 @@ public class NacosConfigService implements ConfigService {
/** /**
* http agent * http agent
*/ */
private ServerHttpAgent agent; private HttpAgent agent;
/** /**
* longpulling * longpolling
*/ */
private ClientWorker worker; private ClientWorker worker;
private String namespace; private String namespace;
@ -79,7 +81,7 @@ public class NacosConfigService implements ConfigService {
namespace = namespaceTmp; namespace = namespaceTmp;
properties.put(PropertyKeyConst.NAMESPACE, namespace); properties.put(PropertyKeyConst.NAMESPACE, namespace);
} }
agent = new ServerHttpAgent(properties); agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
agent.start(); agent.start();
worker = new ClientWorker(agent, configFilterChainManager); worker = new ClientWorker(agent, configFilterChainManager);
} }
@ -131,9 +133,11 @@ public class NacosConfigService implements ConfigService {
try { try {
content = worker.getServerConfig(dataId, group, tenant, timeoutMs); content = worker.getServerConfig(dataId, group, tenant, timeoutMs);
cr.setContent(content); cr.setContent(content);
configFilterChainManager.doFilter(null, cr); configFilterChainManager.doFilter(null, cr);
content = cr.getContent(); content = cr.getContent();
return content; return content;
} catch (NacosException ioe) { } catch (NacosException ioe) {
if (NacosException.NO_RIGHT == ioe.getErrCode()) { if (NacosException.NO_RIGHT == ioe.getErrCode()) {

View File

@ -0,0 +1,98 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.http;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import java.io.IOException;
import java.util.List;
/**
* HttpAgent
*
* @author Nacos
*/
public interface HttpAgent {
/**
* start to get nacos ip list
* @return Nothing.
* @throws NacosException on get ip list error.
*/
void start() throws NacosException;
/**
* invoke http get method
* @param path http path
* @param headers http headers
* @param paramValues http paramValues http
* @param encoding http encode
* @param readTimeoutMs http timeout
* @return HttpResult http response
* @throws IOException If an input or output exception occurred
*/
HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException;
/**
* invoke http post method
* @param path http path
* @param headers http headers
* @param paramValues http paramValues http
* @param encoding http encode
* @param readTimeoutMs http timeout
* @return HttpResult http response
* @throws IOException If an input or output exception occurred
*/
HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException;
/**
* invoke http delete method
* @param path http path
* @param headers http headers
* @param paramValues http paramValues http
* @param encoding http encode
* @param readTimeoutMs http timeout
* @return HttpResult http response
* @throws IOException If an input or output exception occurred
*/
HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException;
/**
* get name
* @return String
*/
String getName();
/**
* get namespace
* @return String
*/
String getNamespace();
/**
* get tenant
* @return String
*/
String getTenant();
/**
* get encode
* @return String
*/
String getEncode();
}

View File

@ -0,0 +1,119 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.http;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* MetricsHttpAgent
*
* @author Nacos
*/
public class MetricsHttpAgent implements HttpAgent {
private HttpAgent httpAgent;
public MetricsHttpAgent(HttpAgent httpAgent) {
this.httpAgent = httpAgent;
}
@Override
public void start() throws NacosException {
httpAgent.start();
}
@Override
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
long start = System.currentTimeMillis();
long end = 0;
HttpResult result = null;
try {
result = httpAgent.httpGet(path, headers, paramValues, encoding, readTimeoutMs);
} catch (IOException e) {
end = System.currentTimeMillis();
MetricsMonitor.getConfigRequestMonitor("GET", path, "NA").record(end - start, TimeUnit.MILLISECONDS);
throw e;
}
end = System.currentTimeMillis();
MetricsMonitor.getConfigRequestMonitor("GET", path, String.valueOf(result.code)).record(end - start, TimeUnit.MILLISECONDS);
return result;
}
@Override
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
long start = System.currentTimeMillis();
long end = 0;
HttpResult result = null;
try {
result = httpAgent.httpPost(path, headers, paramValues, encoding, readTimeoutMs);
} catch (IOException e) {
end = System.currentTimeMillis();
MetricsMonitor.getConfigRequestMonitor("POST", path, "NA").record(end - start, TimeUnit.MILLISECONDS);
throw e;
}
end = System.currentTimeMillis();
MetricsMonitor.getConfigRequestMonitor("POST", path, String.valueOf(result.code)).record(end - start, TimeUnit.MILLISECONDS);
return result;
}
@Override
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
long start = System.currentTimeMillis();
long end = 0;
HttpResult result = null;
try {
result = httpAgent.httpDelete(path, headers, paramValues, encoding, readTimeoutMs);
} catch (IOException e) {
end = System.currentTimeMillis();
MetricsMonitor.getConfigRequestMonitor("DELETE", path, "NA").record(end - start, TimeUnit.MILLISECONDS);
throw e;
}
end = System.currentTimeMillis();
MetricsMonitor.getConfigRequestMonitor("DELETE", path, String.valueOf(result.code)).record(end - start, TimeUnit.MILLISECONDS);
return result;
}
@Override
public String getName() {
return httpAgent.getName();
}
@Override
public String getNamespace() {
return httpAgent.getNamespace();
}
@Override
public String getTenant() {
return httpAgent.getTenant();
}
@Override
public String getEncode() {
return httpAgent.getEncode();
}
}

View File

@ -13,17 +13,21 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.client.config.impl; package com.alibaba.nacos.client.config.http;
import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult; import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.config.impl.ServerListManager;
import com.alibaba.nacos.client.config.impl.SpasAdapter;
import com.alibaba.nacos.client.config.utils.IOUtils; import com.alibaba.nacos.client.config.utils.IOUtils;
import com.alibaba.nacos.client.config.utils.LogUtils; import com.alibaba.nacos.client.config.utils.LogUtils;
import com.alibaba.nacos.client.identify.STSConfig; import com.alibaba.nacos.client.identify.STSConfig;
import com.alibaba.nacos.client.logger.Logger; import com.alibaba.nacos.client.logger.Logger;
import com.alibaba.nacos.client.logger.support.LoggerHelper; import com.alibaba.nacos.client.logger.support.LoggerHelper;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.utils.JSONUtils; import com.alibaba.nacos.client.utils.JSONUtils;
import com.alibaba.nacos.client.utils.ParamUtil; import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.StringUtils; import com.alibaba.nacos.client.utils.StringUtils;
@ -39,13 +43,14 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.TimeUnit;
/** /**
* Server Agent * Server Agent
* *
* @author water.lyl * @author water.lyl
*/ */
public class ServerHttpAgent { public class ServerHttpAgent implements HttpAgent {
final static public Logger log = LogUtils.logger(ServerHttpAgent.class); final static public Logger log = LogUtils.logger(ServerHttpAgent.class);
@ -58,6 +63,7 @@ public class ServerHttpAgent {
* @return * @return
* @throws IOException * @throws IOException
*/ */
@Override
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding, public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding,
long readTimeoutMs) throws IOException { long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs; final long endTime = System.currentTimeMillis() + readTimeoutMs;
@ -101,6 +107,7 @@ public class ServerHttpAgent {
throw new ConnectException("no available server"); throw new ConnectException("no available server");
} }
@Override
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding, public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding,
long readTimeoutMs) throws IOException { long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs; final long endTime = System.currentTimeMillis() + readTimeoutMs;
@ -143,6 +150,7 @@ public class ServerHttpAgent {
throw new ConnectException("no available server"); throw new ConnectException("no available server");
} }
@Override
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding, public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding,
long readTimeoutMs) throws IOException { long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs; final long endTime = System.currentTimeMillis() + readTimeoutMs;
@ -241,6 +249,7 @@ public class ServerHttpAgent {
} }
} }
@Override
public synchronized void start() throws NacosException { public synchronized void start() throws NacosException {
serverListMgr.start(); serverListMgr.start();
} }
@ -324,18 +333,22 @@ public class ServerHttpAgent {
"can not get security credentials, responseCode: " + respCode + ", response: " + response); "can not get security credentials, responseCode: " + respCode + ", response: " + response);
} }
@Override
public String getName() { public String getName() {
return serverListMgr.getName(); return serverListMgr.getName();
} }
@Override
public String getNamespace() { public String getNamespace() {
return serverListMgr.getNamespace(); return serverListMgr.getNamespace();
} }
@Override
public String getTenant() { public String getTenant() {
return serverListMgr.getTenant(); return serverListMgr.getTenant();
} }
@Override
public String getEncode() { public String getEncode() {
return encode; return encode;
} }

View File

@ -20,6 +20,7 @@ import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.common.GroupKey; import com.alibaba.nacos.client.config.common.GroupKey;
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager; import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
import com.alibaba.nacos.client.config.http.HttpAgent;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult; import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.config.utils.ContentUtils; import com.alibaba.nacos.client.config.utils.ContentUtils;
import com.alibaba.nacos.client.config.utils.LogUtils; import com.alibaba.nacos.client.config.utils.LogUtils;
@ -27,6 +28,7 @@ import com.alibaba.nacos.client.config.utils.MD5;
import com.alibaba.nacos.client.config.utils.TenantUtil; import com.alibaba.nacos.client.config.utils.TenantUtil;
import com.alibaba.nacos.client.logger.Logger; import com.alibaba.nacos.client.logger.Logger;
import com.alibaba.nacos.client.logger.support.LoggerHelper; import com.alibaba.nacos.client.logger.support.LoggerHelper;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.utils.ParamUtil; import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.StringUtils; import com.alibaba.nacos.client.utils.StringUtils;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@ -43,7 +45,7 @@ import static com.alibaba.nacos.api.common.Constants.LINE_SEPARATOR;
import static com.alibaba.nacos.api.common.Constants.WORD_SEPARATOR; import static com.alibaba.nacos.api.common.Constants.WORD_SEPARATOR;
/** /**
* Longpulling * Longpolling
* *
* @author Nacos * @author Nacos
*/ */
@ -100,6 +102,8 @@ public class ClientWorker {
cacheMap.set(copy); cacheMap.set(copy);
} }
log.info(agent.getName(), "[unsubscribe] {}", groupKey); log.info(agent.getName(), "[unsubscribe] {}", groupKey);
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
} }
@SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER") @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
@ -111,6 +115,8 @@ public class ClientWorker {
cacheMap.set(copy); cacheMap.set(copy);
} }
log.info(agent.getName(), "[unsubscribe] {}", groupKey); log.info(agent.getName(), "[unsubscribe] {}", groupKey);
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
} }
@SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER") @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
@ -143,6 +149,8 @@ public class ClientWorker {
log.info(agent.getName(), "[subscribe] {}", key); log.info(agent.getName(), "[subscribe] {}", key);
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
return cache; return cache;
} }
@ -170,6 +178,9 @@ public class ClientWorker {
cacheMap.set(copy); cacheMap.set(copy);
} }
log.info(agent.getName(), "[subscribe] {}", key); log.info(agent.getName(), "[subscribe] {}", key);
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
return cache; return cache;
} }
@ -289,7 +300,7 @@ public class ClientWorker {
if (longingTaskCount > currentLongingTaskCount) { if (longingTaskCount > currentLongingTaskCount) {
for (int i = (int)currentLongingTaskCount; i < longingTaskCount; i++) { for (int i = (int)currentLongingTaskCount; i < longingTaskCount; i++) {
// 要判断任务是否在执行 这块需要好好想想 任务列表现在是无序的变化过程可能有问题 // 要判断任务是否在执行 这块需要好好想想 任务列表现在是无序的变化过程可能有问题
executorService.execute(new LongPullingRunnable(i)); executorService.execute(new LongPollingRunnable(i));
} }
currentLongingTaskCount = longingTaskCount; currentLongingTaskCount = longingTaskCount;
} }
@ -406,9 +417,10 @@ public class ClientWorker {
} }
@SuppressWarnings("PMD.ThreadPoolCreationRule") @SuppressWarnings("PMD.ThreadPoolCreationRule")
public ClientWorker(final ServerHttpAgent agent, final ConfigFilterChainManager configFilterChainManager) { public ClientWorker(final HttpAgent agent, final ConfigFilterChainManager configFilterChainManager) {
this.agent = agent; this.agent = agent;
this.configFilterChainManager = configFilterChainManager; this.configFilterChainManager = configFilterChainManager;
executor = Executors.newScheduledThreadPool(1, new ThreadFactory() { executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
@Override @Override
public Thread newThread(Runnable r) { public Thread newThread(Runnable r) {
@ -423,7 +435,7 @@ public class ClientWorker {
@Override @Override
public Thread newThread(Runnable r) { public Thread newThread(Runnable r) {
Thread t = new Thread(r); Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.Worker.longPulling" + agent.getName()); t.setName("com.alibaba.nacos.client.Worker.longPolling" + agent.getName());
t.setDaemon(true); t.setDaemon(true);
return t; return t;
} }
@ -440,10 +452,10 @@ public class ClientWorker {
}, 1L, 10L, TimeUnit.MILLISECONDS); }, 1L, 10L, TimeUnit.MILLISECONDS);
} }
class LongPullingRunnable implements Runnable { class LongPollingRunnable implements Runnable {
private int taskId; private int taskId;
public LongPullingRunnable(int taskId) { public LongPollingRunnable(int taskId) {
this.taskId = taskId; this.taskId = taskId;
} }
@ -498,7 +510,7 @@ public class ClientWorker {
} }
inInitializingCacheList.clear(); inInitializingCacheList.clear();
} catch (Throwable e) { } catch (Throwable e) {
log.error("500", "longPulling error", e); log.error("500", "longPolling error", e);
} finally { } finally {
executorService.execute(this); executorService.execute(this);
} }
@ -522,9 +534,9 @@ public class ClientWorker {
*/ */
AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>( AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(
new HashMap<String, CacheData>()); new HashMap<String, CacheData>());
ServerHttpAgent agent;
HttpAgent agent;
ConfigFilterChainManager configFilterChainManager; ConfigFilterChainManager configFilterChainManager;
private boolean isHealthServer = true; private boolean isHealthServer = true;
private double currentLongingTaskCount = 0; private double currentLongingTaskCount = 0;
} }

View File

@ -42,13 +42,12 @@ public class Limiter {
/** /**
* qps 5 * qps 5
*/ */
private static final String DEFAULT_LIMIT = "5";
private static double limit = 5; private static double limit = 5;
static { static {
try { try {
String limitTimeStr = System String limitTimeStr = System
.getProperty("limitTime", DEFAULT_LIMIT); .getProperty("limitTime", String.valueOf(limit));
limit = Double.parseDouble(limitTimeStr); limit = Double.parseDouble(limitTimeStr);
log.info("limitTime:{}", limit); log.info("limitTime:{}", limit);
} catch (Exception e) { } catch (Exception e) {

View File

@ -104,10 +104,14 @@ public class LocalConfigInfoProcessor {
} }
} else { } else {
try { try {
boolean isMdOk = file.getParentFile().mkdirs(); File parentFile = file.getParentFile();
if (!parentFile.exists()) {
boolean isMdOk = parentFile.mkdirs();
if (!isMdOk) { if (!isMdOk) {
log.error(envName, "NACOS-XXXX", "save snapshot error"); log.error(envName, "NACOS-XXXX", "save snapshot error");
} }
}
if (JVMUtil.isMultiInstance()) { if (JVMUtil.isMultiInstance()) {
ConcurrentDiskUtil.writeFileContent(file, config, ConcurrentDiskUtil.writeFileContent(file, config,
Constants.ENCODE); Constants.ENCODE);

View File

@ -33,6 +33,7 @@ import java.util.Properties;
public abstract class PropertiesListener extends AbstractListener { public abstract class PropertiesListener extends AbstractListener {
final static public Logger log = LogUtils.logger(PropertiesListener.class); final static public Logger log = LogUtils.logger(PropertiesListener.class);
@Override
public void receiveConfigInfo(String configInfo) { public void receiveConfigInfo(String configInfo) {
if (StringUtils.isEmpty(configInfo)) { if (StringUtils.isEmpty(configInfo)) {
return; return;

View File

@ -0,0 +1,81 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.monitor;
import io.micrometer.core.instrument.ImmutableTag;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Timer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Metrics Monitor
*
* @author Nacos
*/
public class MetricsMonitor {
private static AtomicInteger serviceInfoMapSize = new AtomicInteger();
private static AtomicInteger dom2BeatSize = new AtomicInteger();
private static AtomicInteger listenConfigCount = new AtomicInteger();
static {
List<Tag> tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "subServiceCount"));
Metrics.gauge("nacos_monitor", tags, serviceInfoMapSize);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "naming"));
tags.add(new ImmutableTag("name", "pubServiceCount"));
Metrics.gauge("nacos_monitor", tags, dom2BeatSize);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "listenConfigCount"));
Metrics.gauge("nacos_monitor", tags, listenConfigCount);
}
public static AtomicInteger getServiceInfoMapSizeMonitor() {
return serviceInfoMapSize;
}
public static AtomicInteger getDom2BeatSizeMonitor() {
return dom2BeatSize;
}
public static AtomicInteger getListenConfigCountMonitor() {
return listenConfigCount;
}
public static Timer getConfigRequestMonitor(String method, String url, String code) {
return Metrics.timer("nacos_client_request",
"module", "config",
"method", method,
"url", url,
"code", code);
}
public static Timer getNamingRequestMonitor(String method, String url, String code) {
return Metrics.timer("nacos_client_request",
"module", "naming",
"method", method,
"url", url,
"code", code);
}
}

View File

@ -20,7 +20,6 @@ import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.listener.EventListener; import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.pojo.Cluster;
import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView; import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo; import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
@ -36,6 +35,7 @@ import com.alibaba.nacos.client.naming.utils.LogUtils;
import com.alibaba.nacos.client.naming.utils.StringUtils; import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.alibaba.nacos.client.naming.utils.UtilAndComs; import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.math.NumberUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
@ -102,7 +102,7 @@ public class NacosNamingService implements NamingService {
eventDispatcher = new EventDispatcher(); eventDispatcher = new EventDispatcher();
serverProxy = new NamingProxy(namespace, endpoint, serverList); serverProxy = new NamingProxy(namespace, endpoint, serverList);
beatReactor = new BeatReactor(serverProxy); beatReactor = new BeatReactor(serverProxy);
hostReactor = new HostReactor(eventDispatcher, serverProxy, cacheDir, false); hostReactor = new HostReactor(eventDispatcher, serverProxy, cacheDir);
} }
public NacosNamingService(Properties properties) { public NacosNamingService(Properties properties) {
@ -132,10 +132,16 @@ public class NacosNamingService implements NamingService {
properties.getProperty(PropertyKeyConst.NAMING_LOAD_CACHE_AT_START)); properties.getProperty(PropertyKeyConst.NAMING_LOAD_CACHE_AT_START));
} }
int clientBeatThreadCount = NumberUtils.toInt(properties.getProperty(PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT),
UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT);
int pollingThreadCount = NumberUtils.toInt(properties.getProperty(PropertyKeyConst.NAMING_POLLING_THREAD_COUNT),
UtilAndComs.DEFAULT_POLLING_THREAD_COUNT);
eventDispatcher = new EventDispatcher(); eventDispatcher = new EventDispatcher();
serverProxy = new NamingProxy(namespace, endpoint, serverList); serverProxy = new NamingProxy(namespace, endpoint, serverList);
beatReactor = new BeatReactor(serverProxy); beatReactor = new BeatReactor(serverProxy, clientBeatThreadCount);
hostReactor = new HostReactor(eventDispatcher, serverProxy, cacheDir, loadCacheAtStart); hostReactor = new HostReactor(eventDispatcher, serverProxy, cacheDir, loadCacheAtStart, pollingThreadCount);
} }
@ -159,12 +165,13 @@ public class NacosNamingService implements NamingService {
public void registerInstance(String serviceName, Instance instance) throws NacosException { public void registerInstance(String serviceName, Instance instance) throws NacosException {
BeatInfo beatInfo = new BeatInfo(); BeatInfo beatInfo = new BeatInfo();
beatInfo.setDom(serviceName); beatInfo.setServiceName(serviceName);
beatInfo.setIp(instance.getIp()); beatInfo.setIp(instance.getIp());
beatInfo.setPort(instance.getPort()); beatInfo.setPort(instance.getPort());
beatInfo.setCluster(instance.getClusterName()); beatInfo.setCluster(instance.getClusterName());
beatInfo.setWeight(instance.getWeight()); beatInfo.setWeight(instance.getWeight());
beatInfo.setMetadata(instance.getMetadata()); beatInfo.setMetadata(instance.getMetadata());
beatInfo.setScheduled(false);
beatReactor.addBeatInfo(serviceName, beatInfo); beatReactor.addBeatInfo(serviceName, beatInfo);
@ -188,10 +195,24 @@ public class NacosNamingService implements NamingService {
} }
@Override @Override
public List<Instance> getAllInstances(String serviceName, List<String> clusters) throws NacosException { public List<Instance> getAllInstances(String serviceName, boolean subscribe) throws NacosException {
return getAllInstances(serviceName, new ArrayList<String>(), subscribe);
}
ServiceInfo serviceInfo = hostReactor.getServiceInfo(serviceName, StringUtils.join(clusters, ","), @Override
StringUtils.EMPTY, false); public List<Instance> getAllInstances(String serviceName, List<String> clusters) throws NacosException {
return getAllInstances(serviceName, clusters, true);
}
@Override
public List<Instance> getAllInstances(String serviceName, List<String> clusters, boolean subscribe) throws NacosException {
ServiceInfo serviceInfo;
if (subscribe) {
serviceInfo = hostReactor.getServiceInfo(serviceName, StringUtils.join(clusters, ","));
} else {
serviceInfo = hostReactor.getServiceInfoDirectlyFromServer(serviceName, StringUtils.join(clusters, ","));
}
List<Instance> list; List<Instance> list;
if (serviceInfo == null || CollectionUtils.isEmpty(list = serviceInfo.getHosts())) { if (serviceInfo == null || CollectionUtils.isEmpty(list = serviceInfo.getHosts())) {
return new ArrayList<Instance>(); return new ArrayList<Instance>();
@ -200,41 +221,58 @@ public class NacosNamingService implements NamingService {
} }
@Override @Override
public List<Instance> selectInstances(String serviceName, boolean healthyOnly) throws NacosException { public List<Instance> selectInstances(String serviceName, boolean healthy) throws NacosException {
return selectInstances(serviceName, new ArrayList<String>(), healthyOnly); return selectInstances(serviceName, new ArrayList<String>(), healthy);
}
@Override
public List<Instance> selectInstances(String serviceName, boolean healthy, boolean subscribe) throws NacosException {
return selectInstances(serviceName, new ArrayList<String>(), healthy, subscribe);
} }
@Override @Override
public List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy) public List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy)
throws NacosException { throws NacosException {
return selectInstances(serviceName, clusters, healthy, true);
ServiceInfo serviceInfo = hostReactor.getServiceInfo(serviceName, StringUtils.join(clusters, ","),
StringUtils.EMPTY, false);
List<Instance> list;
if (serviceInfo == null || CollectionUtils.isEmpty(list = serviceInfo.getHosts())) {
return new ArrayList<Instance>();
}
Iterator<Instance> iterator = list.iterator();
while (iterator.hasNext()) {
Instance instance = iterator.next();
if (healthy != instance.isHealthy() || !instance.isEnabled() || instance.getWeight() <= 0) {
iterator.remove();
}
}
return list;
} }
@Override @Override
public Instance selectOneHealthyInstance(String serviceName) { public List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy,
boolean subscribe) throws NacosException {
ServiceInfo serviceInfo;
if (subscribe) {
serviceInfo = hostReactor.getServiceInfo(serviceName, StringUtils.join(clusters, ","));
} else {
serviceInfo = hostReactor.getServiceInfoDirectlyFromServer(serviceName, StringUtils.join(clusters, ","));
}
return selectInstances(serviceInfo, healthy);
}
@Override
public Instance selectOneHealthyInstance(String serviceName) throws NacosException {
return selectOneHealthyInstance(serviceName, new ArrayList<String>()); return selectOneHealthyInstance(serviceName, new ArrayList<String>());
} }
@Override @Override
public Instance selectOneHealthyInstance(String serviceName, List<String> clusters) { public Instance selectOneHealthyInstance(String serviceName, boolean subscribe) throws NacosException {
return selectOneHealthyInstance(serviceName, new ArrayList<String>(), subscribe);
}
@Override
public Instance selectOneHealthyInstance(String serviceName, List<String> clusters) throws NacosException {
return selectOneHealthyInstance(serviceName, clusters, true);
}
@Override
public Instance selectOneHealthyInstance(String serviceName, List<String> clusters, boolean subscribe) throws NacosException {
if (subscribe) {
return Balancer.RandomByWeight.selectHost( return Balancer.RandomByWeight.selectHost(
hostReactor.getServiceInfo(serviceName, StringUtils.join(clusters, ","))); hostReactor.getServiceInfo(serviceName, StringUtils.join(clusters, ",")));
} else {
return Balancer.RandomByWeight.selectHost(
hostReactor.getServiceInfoDirectlyFromServer(serviceName, StringUtils.join(clusters, ",")));
}
} }
@Override @Override
@ -271,7 +309,7 @@ public class NacosNamingService implements NamingService {
@Override @Override
public List<ServiceInfo> getSubscribeServices() { public List<ServiceInfo> getSubscribeServices() {
return new ArrayList<ServiceInfo>(hostReactor.getServiceInfoMap().values()); return eventDispatcher.getSubscribeServices();
} }
@Override @Override
@ -279,6 +317,23 @@ public class NacosNamingService implements NamingService {
return serverProxy.serverHealthy() ? "UP" : "DOWN"; return serverProxy.serverHealthy() ? "UP" : "DOWN";
} }
private List<Instance> selectInstances(ServiceInfo serviceInfo, boolean healthy) {
List<Instance> list;
if (serviceInfo == null || CollectionUtils.isEmpty(list = serviceInfo.getHosts())) {
return new ArrayList<Instance>();
}
Iterator<Instance> iterator = list.iterator();
while (iterator.hasNext()) {
Instance instance = iterator.next();
if (healthy != instance.isHealthy() || !instance.isEnabled() || instance.getWeight() <= 0) {
iterator.remove();
}
}
return list;
}
public BeatReactor getBeatReactor() { public BeatReactor getBeatReactor() {
return beatReactor; return beatReactor;
} }

View File

@ -27,21 +27,22 @@ public class BeatInfo {
private int port; private int port;
private String ip; private String ip;
private double weight; private double weight;
private String dom; private String serviceName;
private String cluster; private String cluster;
private Map<String, String> metadata; private Map<String, String> metadata;
private boolean scheduled;
@Override @Override
public String toString() { public String toString() {
return JSON.toJSONString(this); return JSON.toJSONString(this);
} }
public String getDom() { public String getServiceName() {
return dom; return serviceName;
} }
public void setDom(String dom) { public void setServiceName(String serviceName) {
this.dom = dom; this.serviceName = serviceName;
} }
public String getCluster() { public String getCluster() {
@ -83,4 +84,12 @@ public class BeatInfo {
public void setWeight(double weight) { public void setWeight(double weight) {
this.weight = weight; this.weight = weight;
} }
public boolean isScheduled() {
return scheduled;
}
public void setScheduled(boolean scheduled) {
this.scheduled = scheduled;
}
} }

View File

@ -15,14 +15,12 @@
*/ */
package com.alibaba.nacos.client.naming.beat; package com.alibaba.nacos.client.naming.beat;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.net.NamingProxy; import com.alibaba.nacos.client.naming.net.NamingProxy;
import com.alibaba.nacos.client.naming.utils.LogUtils; import com.alibaba.nacos.client.naming.utils.LogUtils;
import com.alibaba.nacos.client.naming.utils.UtilAndComs; import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.*; import java.util.concurrent.*;
@ -31,7 +29,22 @@ import java.util.concurrent.*;
*/ */
public class BeatReactor { public class BeatReactor {
private ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() { private ScheduledExecutorService executorService;
private long clientBeatInterval = 5 * 1000;
private NamingProxy serverProxy;
public final Map<String, BeatInfo> dom2Beat = new ConcurrentHashMap<String, BeatInfo>();
public BeatReactor(NamingProxy serverProxy) {
this(serverProxy, UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT);
}
public BeatReactor(NamingProxy serverProxy, int threadCount) {
this.serverProxy = serverProxy;
executorService = new ScheduledThreadPoolExecutor(threadCount, new ThreadFactory() {
@Override @Override
public Thread newThread(Runnable r) { public Thread newThread(Runnable r) {
Thread thread = new Thread(r); Thread thread = new Thread(r);
@ -41,25 +54,19 @@ public class BeatReactor {
} }
}); });
private long clientBeatInterval = 5 * 1000;
private NamingProxy serverProxy;
public final Map<String, BeatInfo> dom2Beat = new ConcurrentHashMap<String, BeatInfo>();
public BeatReactor(NamingProxy serverProxy) {
this.serverProxy = serverProxy;
executorService.scheduleAtFixedRate(new BeatProcessor(), 0, clientBeatInterval, TimeUnit.MILLISECONDS); executorService.scheduleAtFixedRate(new BeatProcessor(), 0, clientBeatInterval, TimeUnit.MILLISECONDS);
} }
public void addBeatInfo(String dom, BeatInfo beatInfo) { public void addBeatInfo(String dom, BeatInfo beatInfo) {
LogUtils.LOG.info("BEAT", "adding service:" + dom + " to beat map."); LogUtils.LOG.info("BEAT", "adding beat: {} to beat map.", beatInfo);
dom2Beat.put(buildKey(dom, beatInfo.getIp(), beatInfo.getPort()), beatInfo); dom2Beat.put(buildKey(dom, beatInfo.getIp(), beatInfo.getPort()), beatInfo);
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
} }
public void removeBeatInfo(String dom, String ip, int port) { public void removeBeatInfo(String dom, String ip, int port) {
LogUtils.LOG.info("BEAT", "removing service:" + dom + " from beat map."); LogUtils.LOG.info("BEAT", "removing beat: {}:{}:{} from beat map.", dom, ip, port);
dom2Beat.remove(buildKey(dom, ip, port)); dom2Beat.remove(buildKey(dom, ip, port));
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
} }
public String buildKey(String dom, String ip, int port) { public String buildKey(String dom, String ip, int port) {
@ -73,8 +80,11 @@ public class BeatReactor {
try { try {
for (Map.Entry<String, BeatInfo> entry : dom2Beat.entrySet()) { for (Map.Entry<String, BeatInfo> entry : dom2Beat.entrySet()) {
BeatInfo beatInfo = entry.getValue(); BeatInfo beatInfo = entry.getValue();
if (beatInfo.isScheduled()) {
continue;
}
beatInfo.setScheduled(true);
executorService.schedule(new BeatTask(beatInfo), 0, TimeUnit.MILLISECONDS); executorService.schedule(new BeatTask(beatInfo), 0, TimeUnit.MILLISECONDS);
LogUtils.LOG.info("BEAT", "send beat to server: " + beatInfo.toString());
} }
} catch (Exception e) { } catch (Exception e) {
LogUtils.LOG.error("CLIENT-BEAT", "Exception while scheduling beat.", e); LogUtils.LOG.error("CLIENT-BEAT", "Exception while scheduling beat.", e);
@ -83,6 +93,7 @@ public class BeatReactor {
} }
class BeatTask implements Runnable { class BeatTask implements Runnable {
BeatInfo beatInfo; BeatInfo beatInfo;
public BeatTask(BeatInfo beatInfo) { public BeatTask(BeatInfo beatInfo) {
@ -91,20 +102,10 @@ public class BeatReactor {
@Override @Override
public void run() { public void run() {
Map<String, String> params = new HashMap<String, String>(2); long result = serverProxy.sendBeat(beatInfo);
params.put("beat", JSON.toJSONString(beatInfo)); beatInfo.setScheduled(false);
params.put("dom", beatInfo.getDom()); if (result > 0) {
clientBeatInterval = result;
try {
String result = serverProxy.callAllServers(UtilAndComs.NACOS_URL_BASE + "/api/clientBeat", params);
JSONObject jsonObject = JSON.parseObject(result);
if (jsonObject != null) {
clientBeatInterval = jsonObject.getLong("clientBeatInterval");
}
} catch (Exception e) {
LogUtils.LOG.error("CLIENT-BEAT", "failed to send beat: " + JSON.toJSONString(beatInfo), e);
} }
} }
} }

View File

@ -21,7 +21,6 @@ import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo; import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.client.naming.utils.CollectionUtils; import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.client.naming.utils.LogUtils; import com.alibaba.nacos.client.naming.utils.LogUtils;
import com.alibaba.nacos.client.naming.utils.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -57,16 +56,12 @@ public class EventDispatcher {
} }
public void addListener(ServiceInfo serviceInfo, String clusters, EventListener listener) { public void addListener(ServiceInfo serviceInfo, String clusters, EventListener listener) {
addListener(serviceInfo, clusters, StringUtils.EMPTY, listener);
}
public void addListener(ServiceInfo serviceInfo, String clusters, String env, EventListener listener) {
LogUtils.LOG.info("LISTENER", "adding " + serviceInfo.getName() + " with " + clusters + " to listener map"); LogUtils.LOG.info("LISTENER", "adding " + serviceInfo.getName() + " with " + clusters + " to listener map");
List<EventListener> observers = Collections.synchronizedList(new ArrayList<EventListener>()); List<EventListener> observers = Collections.synchronizedList(new ArrayList<EventListener>());
observers.add(listener); observers.add(listener);
observers = observerMap.putIfAbsent(ServiceInfo.getKey(serviceInfo.getName(), clusters, env), observers); observers = observerMap.putIfAbsent(ServiceInfo.getKey(serviceInfo.getName(), clusters), observers);
if (observers != null) { if (observers != null) {
observers.add(listener); observers.add(listener);
} }
@ -77,9 +72,8 @@ public class EventDispatcher {
public void removeListener(String serviceName, String clusters, EventListener listener) { public void removeListener(String serviceName, String clusters, EventListener listener) {
LogUtils.LOG.info("LISTENER", "removing " + serviceName + " with " + clusters + " from listener map"); LogUtils.LOG.info("LISTENER", "removing " + serviceName + " with " + clusters + " from listener map");
String unit = "";
List<EventListener> observers = observerMap.get(ServiceInfo.getKey(serviceName, clusters, unit)); List<EventListener> observers = observerMap.get(ServiceInfo.getKey(serviceName, clusters));
if (observers != null) { if (observers != null) {
Iterator<EventListener> iter = observers.iterator(); Iterator<EventListener> iter = observers.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
@ -88,8 +82,19 @@ public class EventDispatcher {
iter.remove(); iter.remove();
} }
} }
if (observers.isEmpty()) {
observerMap.remove(ServiceInfo.getKey(serviceName, clusters));
} }
} }
}
public List<ServiceInfo> getSubscribeServices() {
List<ServiceInfo> serviceInfos = new ArrayList<ServiceInfo>();
for (String key : observerMap.keySet()) {
serviceInfos.add(ServiceInfo.fromKey(key));
}
return serviceInfos;
}
public void serviceChanged(ServiceInfo serviceInfo) { public void serviceChanged(ServiceInfo serviceInfo) {
if (serviceInfo == null) { if (serviceInfo == null) {

View File

@ -16,13 +16,14 @@
package com.alibaba.nacos.client.naming.core; package com.alibaba.nacos.client.naming.core;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo; import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.backups.FailoverReactor; import com.alibaba.nacos.client.naming.backups.FailoverReactor;
import com.alibaba.nacos.client.naming.cache.DiskCache; import com.alibaba.nacos.client.naming.cache.DiskCache;
import com.alibaba.nacos.client.naming.net.NamingProxy; import com.alibaba.nacos.client.naming.net.NamingProxy;
import com.alibaba.nacos.client.naming.utils.LogUtils; import com.alibaba.nacos.client.naming.utils.LogUtils;
import com.alibaba.nacos.client.naming.utils.NetUtils;
import com.alibaba.nacos.client.naming.utils.StringUtils; import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.alibaba.nacos.client.naming.utils.UtilAndComs; import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@ -45,7 +46,7 @@ public class HostReactor {
private Map<String, Object> updatingMap; private Map<String, Object> updatingMap;
private PushRecver pushRecver; private PushReceiver pushReceiver;
private EventDispatcher eventDispatcher; private EventDispatcher eventDispatcher;
@ -55,8 +56,25 @@ public class HostReactor {
private String cacheDir; private String cacheDir;
private ScheduledExecutorService executor;
public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, String cacheDir) {
this(eventDispatcher, serverProxy, cacheDir, false, UtilAndComs.DEFAULT_POLLING_THREAD_COUNT);
}
public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, String cacheDir, public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, String cacheDir,
boolean loadCacheAtStart) { boolean loadCacheAtStart, int pollingThreadCount) {
executor = new ScheduledThreadPoolExecutor(pollingThreadCount, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);
thread.setName("com.alibaba.nacos.client.naming.updater");
return thread;
}
});
this.eventDispatcher = eventDispatcher; this.eventDispatcher = eventDispatcher;
this.serverProxy = serverProxy; this.serverProxy = serverProxy;
this.cacheDir = cacheDir; this.cacheDir = cacheDir;
@ -68,19 +86,9 @@ public class HostReactor {
this.updatingMap = new ConcurrentHashMap<String, Object>(); this.updatingMap = new ConcurrentHashMap<String, Object>();
this.failoverReactor = new FailoverReactor(this, cacheDir); this.failoverReactor = new FailoverReactor(this, cacheDir);
this.pushRecver = new PushRecver(this); this.pushReceiver = new PushReceiver(this);
} }
private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, "com.alibaba.nacos.client.naming.updater");
thread.setDaemon(true);
return thread;
}
});
public Map<String, ServiceInfo> getServiceInfoMap() { public Map<String, ServiceInfo> getServiceInfoMap() {
return serviceInfoMap; return serviceInfoMap;
} }
@ -182,61 +190,46 @@ public class HostReactor {
DiskCache.write(serviceInfo, cacheDir); DiskCache.write(serviceInfo, cacheDir);
} }
MetricsMonitor.getServiceInfoMapSizeMonitor().set(serviceInfoMap.size());
LogUtils.LOG.info("current ips:(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getName() + LogUtils.LOG.info("current ips:(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getName() +
" -> " + JSON.toJSONString(serviceInfo.getHosts())); " -> " + JSON.toJSONString(serviceInfo.getHosts()));
return serviceInfo; return serviceInfo;
} }
private ServiceInfo getSerivceInfo0(String serviceName, String clusters, String env) { private ServiceInfo getSerivceInfo0(String serviceName, String clusters) {
String key = ServiceInfo.getKey(serviceName, clusters, env, false); String key = ServiceInfo.getKey(serviceName, clusters);
return serviceInfoMap.get(key); return serviceInfoMap.get(key);
} }
private ServiceInfo getSerivceInfo0(String serviceName, String clusters, String env, boolean allIPs) { public ServiceInfo getServiceInfoDirectlyFromServer(final String serviceName, final String clusters) throws NacosException {
String result = serverProxy.queryList(serviceName, clusters, 0, false);
String key = ServiceInfo.getKey(serviceName, clusters, env, allIPs); if (StringUtils.isNotEmpty(result)) {
return serviceInfoMap.get(key); return JSON.parseObject(result, ServiceInfo.class);
}
return null;
} }
public ServiceInfo getServiceInfo(String serviceName, String clusters, String env) { public ServiceInfo getServiceInfo(final String serviceName, final String clusters) {
return getServiceInfo(serviceName, clusters, env, false);
}
public ServiceInfo getServiceInfo(String serviceName, String clusters) {
String env = StringUtils.EMPTY;
return getServiceInfo(serviceName, clusters, env, false);
}
public ServiceInfo getServiceInfo(final String serviceName, final String clusters, final String env,
final boolean allIPs) {
LogUtils.LOG.debug("failover-mode: " + failoverReactor.isFailoverSwitch()); LogUtils.LOG.debug("failover-mode: " + failoverReactor.isFailoverSwitch());
String key = ServiceInfo.getKey(serviceName, clusters, env, allIPs); String key = ServiceInfo.getKey(serviceName, clusters);
if (failoverReactor.isFailoverSwitch()) { if (failoverReactor.isFailoverSwitch()) {
return failoverReactor.getService(key); return failoverReactor.getService(key);
} }
ServiceInfo serviceObj = getSerivceInfo0(serviceName, clusters, env, allIPs); ServiceInfo serviceObj = getSerivceInfo0(serviceName, clusters);
if (null == serviceObj) { if (null == serviceObj) {
serviceObj = new ServiceInfo(serviceName, clusters, env); serviceObj = new ServiceInfo(serviceName, clusters);
if (allIPs) {
serviceObj.setAllIPs(allIPs);
}
serviceInfoMap.put(serviceObj.getKey(), serviceObj); serviceInfoMap.put(serviceObj.getKey(), serviceObj);
updatingMap.put(serviceName, new Object()); updatingMap.put(serviceName, new Object());
updateServiceNow(serviceName, clusters);
if (allIPs) {
updateService4AllIPNow(serviceName, clusters, env);
} else {
updateServiceNow(serviceName, clusters, env);
}
updatingMap.remove(serviceName); updatingMap.remove(serviceName);
} else if (updatingMap.containsKey(serviceName)) { } else if (updatingMap.containsKey(serviceName)) {
@ -248,100 +241,41 @@ public class HostReactor {
serviceObj.wait(updateHoldInterval); serviceObj.wait(updateHoldInterval);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LogUtils.LOG.error("[getServiceInfo]", LogUtils.LOG.error("[getServiceInfo]",
"serviceName:" + serviceName + ", clusters:" + clusters + ", allIPs:" + allIPs, e); "serviceName:" + serviceName + ", clusters:" + clusters, e);
} }
} }
} }
} }
scheduleUpdateIfAbsent(serviceName, clusters, env, allIPs); scheduleUpdateIfAbsent(serviceName, clusters);
return serviceInfoMap.get(serviceObj.getKey()); return serviceInfoMap.get(serviceObj.getKey());
} }
public void scheduleUpdateIfAbsent(String serviceName, String clusters, String env, boolean allIPs) { public void scheduleUpdateIfAbsent(String serviceName, String clusters) {
if (futureMap.get(ServiceInfo.getKey(serviceName, clusters, env, allIPs)) != null) { if (futureMap.get(ServiceInfo.getKey(serviceName, clusters)) != null) {
return; return;
} }
synchronized (futureMap) { synchronized (futureMap) {
if (futureMap.get(ServiceInfo.getKey(serviceName, clusters, env, allIPs)) != null) { if (futureMap.get(ServiceInfo.getKey(serviceName, clusters)) != null) {
return; return;
} }
ScheduledFuture<?> future = addTask(new UpdateTask(serviceName, clusters, env, allIPs)); ScheduledFuture<?> future = addTask(new UpdateTask(serviceName, clusters));
futureMap.put(ServiceInfo.getKey(serviceName, clusters, env, allIPs), future); futureMap.put(ServiceInfo.getKey(serviceName, clusters), future);
}
}
public void updateService4AllIPNow(String serviceName, String clusters, String env) {
updateService4AllIPNow(serviceName, clusters, env, -1L);
}
@SuppressFBWarnings("NN_NAKED_NOTIFY")
public void updateService4AllIPNow(String serviceName, String clusters, String env, long timeout) {
try {
Map<String, String> params = new HashMap<String, String>(8);
params.put("dom", serviceName);
params.put("clusters", clusters);
params.put("udpPort", String.valueOf(pushRecver.getUDPPort()));
ServiceInfo oldService = getSerivceInfo0(serviceName, clusters, env, true);
if (oldService != null) {
params.put("checksum", oldService.getChecksum());
}
String result = serverProxy.reqAPI(UtilAndComs.NACOS_URL_BASE + "/api/srvAllIP", params);
if (StringUtils.isNotEmpty(result)) {
ServiceInfo serviceInfo = processServiceJSON(result);
serviceInfo.setAllIPs(true);
}
if (oldService != null) {
synchronized (oldService) {
oldService.notifyAll();
}
}
//else nothing has changed
} catch (Exception e) {
LogUtils.LOG.error("NA", "failed to update serviceName: " + serviceName, e);
} }
} }
@SuppressFBWarnings("NN_NAKED_NOTIFY") @SuppressFBWarnings("NN_NAKED_NOTIFY")
public void updateServiceNow(String serviceName, String clusters, String env) { public void updateServiceNow(String serviceName, String clusters) {
ServiceInfo oldService = getSerivceInfo0(serviceName, clusters, env); ServiceInfo oldService = getSerivceInfo0(serviceName, clusters);
try { try {
Map<String, String> params = new HashMap<String, String>(8);
params.put("dom", serviceName);
params.put("clusters", clusters);
params.put("udpPort", String.valueOf(pushRecver.getUDPPort()));
params.put("env", env);
params.put("clientIP", NetUtils.localIP());
StringBuilder stringBuilder = new StringBuilder(); String result = serverProxy.queryList(serviceName, clusters, pushReceiver.getUDPPort(), false);
for (String string : Balancer.UNCONSISTENT_SERVICE_WITH_ADDRESS_SERVER) {
stringBuilder.append(string).append(",");
}
Balancer.UNCONSISTENT_SERVICE_WITH_ADDRESS_SERVER.clear();
params.put("unconsistentDom", stringBuilder.toString());
String envSpliter = ",";
if (!StringUtils.isEmpty(env) && !env.contains(envSpliter)) {
params.put("useEnvId", "true");
}
if (oldService != null) {
params.put("checksum", oldService.getChecksum());
}
String result = serverProxy.reqAPI(UtilAndComs.NACOS_URL_BASE + "/api/srvIPXT", params);
if (StringUtils.isNotEmpty(result)) { if (StringUtils.isNotEmpty(result)) {
processServiceJSON(result); processServiceJSON(result);
} }
//else nothing has changed
} catch (Exception e) { } catch (Exception e) {
LogUtils.LOG.error("NA", "failed to update serviceName: " + serviceName, e); LogUtils.LOG.error("NA", "failed to update serviceName: " + serviceName, e);
} finally { } finally {
@ -353,34 +287,9 @@ public class HostReactor {
} }
} }
public void refreshOnly(String serviceName, String clusters, String env, boolean allIPs) { public void refreshOnly(String serviceName, String clusters) {
try { try {
Map<String, String> params = new HashMap<String, String>(16); serverProxy.queryList(serviceName, clusters, pushReceiver.getUDPPort(), false);
params.put("dom", serviceName);
params.put("clusters", clusters);
params.put("udpPort", String.valueOf(pushRecver.getUDPPort()));
params.put("unit", env);
params.put("clientIP", NetUtils.localIP());
String serviceSpliter = ",";
StringBuilder stringBuilder = new StringBuilder();
for (String string : Balancer.UNCONSISTENT_SERVICE_WITH_ADDRESS_SERVER) {
stringBuilder.append(string).append(serviceSpliter);
}
Balancer.UNCONSISTENT_SERVICE_WITH_ADDRESS_SERVER.clear();
params.put("unconsistentDom", stringBuilder.toString());
String envSpliter = ",";
if (!env.contains(envSpliter)) {
params.put("useEnvId", "true");
}
if (allIPs) {
serverProxy.reqAPI(UtilAndComs.NACOS_URL_BASE + "/api/srvAllIP", params);
} else {
serverProxy.reqAPI(UtilAndComs.NACOS_URL_BASE + "/api/srvIPXT", params);
}
} catch (Exception e) { } catch (Exception e) {
LogUtils.LOG.error("NA", "failed to update serviceName: " + serviceName, e); LogUtils.LOG.error("NA", "failed to update serviceName: " + serviceName, e);
} }
@ -390,50 +299,30 @@ public class HostReactor {
long lastRefTime = Long.MAX_VALUE; long lastRefTime = Long.MAX_VALUE;
private String clusters; private String clusters;
private String serviceName; private String serviceName;
private String env;
private boolean allIPs = false;
public UpdateTask(String serviceName, String clusters, String env) { public UpdateTask(String serviceName, String clusters) {
this.serviceName = serviceName; this.serviceName = serviceName;
this.clusters = clusters; this.clusters = clusters;
this.env = env;
}
public UpdateTask(String serviceName, String clusters, String env, boolean allIPs) {
this.serviceName = serviceName;
this.clusters = clusters;
this.env = env;
this.allIPs = allIPs;
} }
@Override @Override
public void run() { public void run() {
try { try {
ServiceInfo serviceObj = serviceInfoMap.get(ServiceInfo.getKey(serviceName, clusters, env, allIPs)); ServiceInfo serviceObj = serviceInfoMap.get(ServiceInfo.getKey(serviceName, clusters));
if (serviceObj == null) { if (serviceObj == null) {
if (allIPs) { updateServiceNow(serviceName, clusters);
updateService4AllIPNow(serviceName, clusters, env);
} else {
updateServiceNow(serviceName, clusters, env);
executor.schedule(this, DEFAULT_DELAY, TimeUnit.MILLISECONDS); executor.schedule(this, DEFAULT_DELAY, TimeUnit.MILLISECONDS);
}
return; return;
} }
if (serviceObj.getLastRefTime() <= lastRefTime) { if (serviceObj.getLastRefTime() <= lastRefTime) {
if (allIPs) { updateServiceNow(serviceName, clusters);
updateService4AllIPNow(serviceName, clusters, env); serviceObj = serviceInfoMap.get(ServiceInfo.getKey(serviceName, clusters));
serviceObj = serviceInfoMap.get(ServiceInfo.getKey(serviceName, clusters, env, true));
} else {
updateServiceNow(serviceName, clusters, env);
serviceObj = serviceInfoMap.get(ServiceInfo.getKey(serviceName, clusters, env));
}
} else { } else {
// if serviceName already updated by push, we should not override it // if serviceName already updated by push, we should not override it
// since the push data may be different from pull through force push // since the push data may be different from pull through force push
refreshOnly(serviceName, clusters, env, allIPs); refreshOnly(serviceName, clusters);
} }
executor.schedule(this, serviceObj.getCacheMillis(), TimeUnit.MILLISECONDS); executor.schedule(this, serviceObj.getCacheMillis(), TimeUnit.MILLISECONDS);

View File

@ -30,7 +30,7 @@ import java.util.concurrent.ThreadFactory;
/** /**
* @author xuanyin * @author xuanyin
*/ */
public class PushRecver implements Runnable { public class PushReceiver implements Runnable {
private ScheduledExecutorService executorService; private ScheduledExecutorService executorService;
@ -40,7 +40,7 @@ public class PushRecver implements Runnable {
private HostReactor hostReactor; private HostReactor hostReactor;
public PushRecver(HostReactor hostReactor) { public PushReceiver(HostReactor hostReactor) {
try { try {
this.hostReactor = hostReactor; this.hostReactor = hostReactor;
udpSocket = new DatagramSocket(); udpSocket = new DatagramSocket();

View File

@ -18,13 +18,17 @@ package com.alibaba.nacos.client.naming.net;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView; import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.selector.AbstractSelector; import com.alibaba.nacos.api.selector.AbstractSelector;
import com.alibaba.nacos.api.selector.SelectorType;
import com.alibaba.nacos.api.selector.ExpressionSelector; import com.alibaba.nacos.api.selector.ExpressionSelector;
import com.alibaba.nacos.api.selector.SelectorType;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.beat.BeatInfo;
import com.alibaba.nacos.client.naming.utils.*; import com.alibaba.nacos.client.naming.utils.*;
import com.alibaba.nacos.common.util.HttpMethod;
import com.alibaba.nacos.common.util.UuidUtils; import com.alibaba.nacos.common.util.UuidUtils;
import java.io.IOException; import java.io.IOException;
@ -43,7 +47,7 @@ public class NamingProxy {
private static final int DEFAULT_SERVER_PORT = 8848; private static final int DEFAULT_SERVER_PORT = 8848;
private String namespace; private String namespaceId;
private String endpoint; private String endpoint;
@ -59,9 +63,9 @@ public class NamingProxy {
private ScheduledExecutorService executorService; private ScheduledExecutorService executorService;
public NamingProxy(String namespace, String endpoint, String serverList) { public NamingProxy(String namespaceId, String endpoint, String serverList) {
this.namespace = namespace; this.namespaceId = namespaceId;
this.endpoint = endpoint; this.endpoint = endpoint;
if (StringUtils.isNotEmpty(serverList)) { if (StringUtils.isNotEmpty(serverList)) {
this.serverList = Arrays.asList(serverList.split(",")); this.serverList = Arrays.asList(serverList.split(","));
@ -154,10 +158,11 @@ public class NamingProxy {
public void registerService(String serviceName, Instance instance) throws NacosException { public void registerService(String serviceName, Instance instance) throws NacosException {
LogUtils.LOG.info("REGISTER-SERVICE", "registering service " + serviceName + " with instance:" + instance); LogUtils.LOG.info("REGISTER-SERVICE", "{} registering service {} with instance: {}",
namespaceId, serviceName, instance);
final Map<String, String> params = new HashMap<String, String>(8); final Map<String, String> params = new HashMap<String, String>(8);
params.put("tenant", namespace); params.put(Constants.REQUEST_PARAM_NAMESPACE_ID, namespaceId);
params.put("ip", instance.getIp()); params.put("ip", instance.getIp());
params.put("port", String.valueOf(instance.getPort())); params.put("port", String.valueOf(instance.getPort()));
params.put("weight", String.valueOf(instance.getWeight())); params.put("weight", String.valueOf(instance.getWeight()));
@ -167,33 +172,55 @@ public class NamingProxy {
params.put("serviceName", serviceName); params.put("serviceName", serviceName);
params.put("clusterName", instance.getClusterName()); params.put("clusterName", instance.getClusterName());
reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, "PUT"); reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.POST);
} }
public void deregisterService(String serviceName, String ip, int port, String cluster) throws NacosException { public void deregisterService(String serviceName, String ip, int port, String cluster) throws NacosException {
LogUtils.LOG.info("DEREGISTER-SERVICE", "deregistering service " + serviceName LogUtils.LOG.info("DEREGISTER-SERVICE", "{} deregistering service {} with instance: {}:{}@{}",
+ " with instance:" + ip + ":" + port + "@" + cluster); namespaceId, serviceName, ip, port, cluster);
final Map<String, String> params = new HashMap<String, String>(8); final Map<String, String> params = new HashMap<String, String>(8);
params.put("tenant", namespace); params.put(Constants.REQUEST_PARAM_NAMESPACE_ID, namespaceId);
params.put("ip", ip); params.put("ip", ip);
params.put("port", String.valueOf(port)); params.put("port", String.valueOf(port));
params.put("serviceName", serviceName); params.put("serviceName", serviceName);
params.put("cluster", cluster); params.put("cluster", cluster);
reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, "DELETE"); reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.DELETE);
} }
public String queryList(String serviceName, String clusters, boolean healthyOnly) throws NacosException { public String queryList(String serviceName, String clusters, int udpPort, boolean healthyOnly) throws NacosException {
final Map<String, String> params = new HashMap<String, String>(8); final Map<String, String> params = new HashMap<String, String>(8);
params.put("tenant", namespace); params.put(Constants.REQUEST_PARAM_NAMESPACE_ID, namespaceId);
params.put("serviceName", serviceName); params.put("serviceName", serviceName);
params.put("clusters", clusters); params.put("clusters", clusters);
params.put("udpPort", String.valueOf(udpPort));
params.put("clientIP", NetUtils.localIP());
params.put("healthyOnly", String.valueOf(healthyOnly)); params.put("healthyOnly", String.valueOf(healthyOnly));
return reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/list", params, "GET"); return reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/list", params, HttpMethod.GET);
}
public long sendBeat(BeatInfo beatInfo) {
try {
LogUtils.LOG.info("BEAT", "{} sending beat to server: {}", namespaceId, beatInfo.toString());
Map<String, String> params = new HashMap<String, String>(4);
params.put("beat", JSON.toJSONString(beatInfo));
params.put(Constants.REQUEST_PARAM_NAMESPACE_ID, namespaceId);
params.put("serviceName", beatInfo.getServiceName());
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/beat", params, HttpMethod.PUT);
JSONObject jsonObject = JSON.parseObject(result);
if (jsonObject != null) {
return jsonObject.getLong("clientBeatInterval");
}
} catch (Exception e) {
LogUtils.LOG.error("CLIENT-BEAT", "failed to send beat: " + JSON.toJSONString(beatInfo), e);
}
return 0L;
} }
public boolean serverHealthy() { public boolean serverHealthy() {
@ -216,6 +243,7 @@ public class NamingProxy {
Map<String, String> params = new HashMap<String, String>(4); Map<String, String> params = new HashMap<String, String>(4);
params.put("pageNo", String.valueOf(pageNo)); params.put("pageNo", String.valueOf(pageNo));
params.put("pageSize", String.valueOf(pageSize)); params.put("pageSize", String.valueOf(pageSize));
params.put(Constants.REQUEST_PARAM_NAMESPACE_ID, namespaceId);
if (selector != null) { if (selector != null) {
switch (SelectorType.valueOf(selector.getType())) { switch (SelectorType.valueOf(selector.getType())) {
@ -241,27 +269,6 @@ public class NamingProxy {
return listView; return listView;
} }
public String callAllServers(String api, Map<String, String> params) throws NacosException {
String result = "";
List<String> snapshot = serversFromEndpoint;
if (!CollectionUtils.isEmpty(serverList)) {
snapshot = serverList;
}
try {
result = reqAPI(api, params, snapshot);
} catch (Exception e) {
LogUtils.LOG.error("NA", "req api:" + api + " failed, servers: " + snapshot, e);
}
if (StringUtils.isNotEmpty(result)) {
return result;
}
throw new IllegalStateException("failed to req API:/api/" + api + " after all sites(" + snapshot + ") tried");
}
public String reqAPI(String api, Map<String, String> params) throws NacosException { public String reqAPI(String api, Map<String, String> params) throws NacosException {
@ -284,11 +291,13 @@ public class NamingProxy {
} }
public String callServer(String api, Map<String, String> params, String curServer) throws NacosException { public String callServer(String api, Map<String, String> params, String curServer) throws NacosException {
return callServer(api, params, curServer, "GET"); return callServer(api, params, curServer, HttpMethod.GET);
} }
public String callServer(String api, Map<String, String> params, String curServer, String method) public String callServer(String api, Map<String, String> params, String curServer, String method)
throws NacosException { throws NacosException {
long start = System.currentTimeMillis();
long end = 0;
List<String> headers = Arrays.asList("Client-Version", UtilAndComs.VERSION, List<String> headers = Arrays.asList("Client-Version", UtilAndComs.VERSION,
"Accept-Encoding", "gzip,deflate,sdch", "Accept-Encoding", "gzip,deflate,sdch",
@ -304,6 +313,10 @@ public class NamingProxy {
url = HttpClient.getPrefix() + curServer + api; url = HttpClient.getPrefix() + curServer + api;
HttpClient.HttpResult result = HttpClient.request(url, headers, params, UtilAndComs.ENCODING, method); HttpClient.HttpResult result = HttpClient.request(url, headers, params, UtilAndComs.ENCODING, method);
end = System.currentTimeMillis();
MetricsMonitor.getNamingRequestMonitor(method, url, String.valueOf(result.code))
.record(end - start, TimeUnit.MILLISECONDS);
if (HttpURLConnection.HTTP_OK == result.code) { if (HttpURLConnection.HTTP_OK == result.code) {
return result.content; return result.content;
@ -323,11 +336,13 @@ public class NamingProxy {
} }
public String reqAPI(String api, Map<String, String> params, List<String> servers) { public String reqAPI(String api, Map<String, String> params, List<String> servers) {
return reqAPI(api, params, servers, "GET"); return reqAPI(api, params, servers, HttpMethod.GET);
} }
public String reqAPI(String api, Map<String, String> params, List<String> servers, String method) { public String reqAPI(String api, Map<String, String> params, List<String> servers, String method) {
params.put(Constants.REQUEST_PARAM_NAMESPACE_ID, getNamespaceId());
if (CollectionUtils.isEmpty(servers) && StringUtils.isEmpty(nacosDomain)) { if (CollectionUtils.isEmpty(servers) && StringUtils.isEmpty(nacosDomain)) {
throw new IllegalArgumentException("no server available"); throw new IllegalArgumentException("no server available");
} }
@ -363,4 +378,7 @@ public class NamingProxy {
} }
public String getNamespaceId() {
return namespaceId;
}
} }

View File

@ -34,7 +34,7 @@ public class UtilAndComs {
public static final String NACOS_URL_INSTANCE = NACOS_URL_BASE + "/instance"; public static final String NACOS_URL_INSTANCE = NACOS_URL_BASE + "/instance";
public static final String DEFAULT_NAMESPACE_ID = "default"; public static final String DEFAULT_NAMESPACE_ID = "public";
public static final int REQUEST_DOMAIN_RETRY_COUNT = 3; public static final int REQUEST_DOMAIN_RETRY_COUNT = 3;
@ -45,4 +45,10 @@ public class UtilAndComs {
public static final String NACOS_NAMING_LOG_LEVEL = "com.alibaba.nacos.naming.log.level"; public static final String NACOS_NAMING_LOG_LEVEL = "com.alibaba.nacos.naming.log.level";
public static final String SERVER_ADDR_IP_SPLITER = ":"; public static final String SERVER_ADDR_IP_SPLITER = ":";
public static final int DEFAULT_CLIENT_BEAT_THREAD_COUNT = Runtime.getRuntime().availableProcessors() > 1 ?
Runtime.getRuntime().availableProcessors() / 2 : 1;
public static final int DEFAULT_POLLING_THREAD_COUNT = Runtime.getRuntime().availableProcessors() > 1 ?
Runtime.getRuntime().availableProcessors() / 2 : 1;
} }

View File

@ -16,6 +16,8 @@
package com.alibaba.nacos.client; package com.alibaba.nacos.client;
import com.alibaba.nacos.api.NacosFactory; import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView; import com.alibaba.nacos.api.naming.pojo.ListView;
@ -25,6 +27,7 @@ import org.junit.Test;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
@ -35,7 +38,11 @@ public class NamingTest {
@Ignore @Ignore
public void testServiceList() throws Exception { public void testServiceList() throws Exception {
NamingService namingService = NacosFactory.createNamingService("127.0.0.1:8848"); Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, "11.160.165.126:8848");
properties.put(PropertyKeyConst.NAMESPACE, "t1");
NamingService namingService = NacosFactory.createNamingService(properties);
Instance instance = new Instance(); Instance instance = new Instance();
instance.setIp("1.1.1.1"); instance.setIp("1.1.1.1");
@ -48,9 +55,9 @@ public class NamingTest {
namingService.registerInstance("nacos.test.1", instance); namingService.registerInstance("nacos.test.1", instance);
ExpressionSelector expressionSelector = new ExpressionSelector(); // ExpressionSelector expressionSelector = new ExpressionSelector();
expressionSelector.setExpression("INSTANCE.metadata.registerSource = 'dubbo'"); // expressionSelector.setExpression("INSTANCE.metadata.registerSource = 'dubbo'");
ListView<String> serviceList = namingService.getServicesOfServer(1, 10, expressionSelector); // ListView<String> serviceList = namingService.getServicesOfServer(1, 10, expressionSelector);
Thread.sleep(1000000000L); Thread.sleep(1000000000L);
} }

View File

@ -18,7 +18,7 @@
<parent> <parent>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<version>0.7.0</version> <version>0.8.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -20,6 +20,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
@SpringBootApplication @SpringBootApplication
public class CmdbApp { public class CmdbApp {

View File

@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletRequest;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
@RestController @RestController
@RequestMapping(UtilsAndCommons.NACOS_CMDB_CONTEXT + "/ops") @RequestMapping(UtilsAndCommons.NACOS_CMDB_CONTEXT + "/ops")

View File

@ -17,6 +17,7 @@ package com.alibaba.nacos.cmdb.core;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public class CmdbManager { public class CmdbManager {
} }

View File

@ -20,6 +20,7 @@ import org.springframework.stereotype.Component;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
@Component @Component
public class SwitchAndOptions { public class SwitchAndOptions {

View File

@ -36,6 +36,7 @@ import java.util.concurrent.TimeUnit;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
@Component @Component
public class CmdbProvider implements CmdbReader, CmdbWriter { public class CmdbProvider implements CmdbReader, CmdbWriter {

View File

@ -22,6 +22,7 @@ import java.util.List;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public interface CmdbReader { public interface CmdbReader {

View File

@ -17,6 +17,7 @@ package com.alibaba.nacos.cmdb.service;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public interface CmdbWriter { public interface CmdbWriter {
} }

View File

@ -20,6 +20,7 @@ import org.slf4j.LoggerFactory;
/** /**
* @author nacos * @author nacos
* @since 0.7.0
*/ */
public class Loggers { public class Loggers {

View File

@ -21,6 +21,7 @@ import java.util.concurrent.ThreadFactory;
/** /**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a> * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.7.0
*/ */
public class UtilsAndCommons { public class UtilsAndCommons {

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>0.7.0</version> <version>0.8.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -0,0 +1,39 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.util;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @since 0.8.0
*/
public class HttpMethod {
public static final String GET = "GET";
public static final String HEAD = "HEAD";
public static final String POST = "POST";
public static final String PUT = "PUT";
public static final String PATCH = "PATCH";
public static final String DELETE = "DELETE";
public static final String OPTIONS = "PATCH";
public static final String TRACE = "TRACE";
}

View File

@ -17,7 +17,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>0.7.0</version> <version>0.8.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -126,6 +126,26 @@
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
<version>3.4</version> <version>3.4</version>
</dependency> </dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-influx</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-elastic</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>

View File

@ -17,6 +17,7 @@ package com.alibaba.nacos.config.server;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.net.UnknownHostException; import java.net.UnknownHostException;
@ -25,6 +26,7 @@ import java.net.UnknownHostException;
* *
* @author Nacos * @author Nacos
*/ */
@EnableScheduling
@SpringBootApplication @SpringBootApplication
public class Config { public class Config {

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.config.server.aspect; package com.alibaba.nacos.config.server.aspect;
import com.alibaba.nacos.config.server.service.ConfigService; import com.alibaba.nacos.config.server.service.ConfigService;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.utils.GroupKey2; import com.alibaba.nacos.config.server.utils.GroupKey2;
import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.LogUtil;
import com.alibaba.nacos.config.server.utils.MD5; import com.alibaba.nacos.config.server.utils.MD5;
@ -23,6 +24,7 @@ import com.alibaba.nacos.config.server.utils.RequestUtil;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -33,8 +35,8 @@ import javax.servlet.http.HttpServletResponse;
* @author Nacos * @author Nacos
*/ */
@Aspect @Aspect
@Component
public class RequestLogAspect { public class RequestLogAspect {
/** /**
* publish config * publish config
*/ */
@ -54,22 +56,24 @@ public class RequestLogAspect {
*/ */
private static final String CLIENT_INTERFACE_REMOVE_ALL_CONFIG private static final String CLIENT_INTERFACE_REMOVE_ALL_CONFIG
= "execution(* com.alibaba.nacos.config.server.controller.ConfigController.deleteConfig(..)) && args(request," = "execution(* com.alibaba.nacos.config.server.controller.ConfigController.deleteConfig(..)) && args(request,"
+ "response,dataId,group,..)"; + "response,dataId,group,tenant,..)";
/** /**
* publishSingle * publishSingle
*/ * */
@Around(CLIENT_INTERFACE_PUBLISH_SINGLE_CONFIG) @Around(CLIENT_INTERFACE_PUBLISH_SINGLE_CONFIG)
public Object interfacePublishSingle(ProceedingJoinPoint pjp, HttpServletRequest request, public Object interfacePublishSingle(ProceedingJoinPoint pjp, HttpServletRequest request,
HttpServletResponse response, String dataId, String group, String tenant, HttpServletResponse response, String dataId, String group, String tenant,
String content) throws Throwable { String content) throws Throwable {
final String md5 = content == null ? null : MD5.getInstance().getMD5String(content); final String md5 = content == null ? null : MD5.getInstance().getMD5String(content);
MetricsMonitor.getPublishMonitor().incrementAndGet();
return logClientRequest("publish", pjp, request, response, dataId, group, tenant, md5); return logClientRequest("publish", pjp, request, response, dataId, group, tenant, md5);
} }
/** /**
* removeAll * removeAll
*/ * */
@Around(CLIENT_INTERFACE_REMOVE_ALL_CONFIG) @Around(CLIENT_INTERFACE_REMOVE_ALL_CONFIG)
public Object interfaceRemoveAll(ProceedingJoinPoint pjp, HttpServletRequest request, HttpServletResponse response, public Object interfaceRemoveAll(ProceedingJoinPoint pjp, HttpServletRequest request, HttpServletResponse response,
String dataId, String group, String tenant) throws Throwable { String dataId, String group, String tenant) throws Throwable {
@ -84,6 +88,7 @@ public class RequestLogAspect {
String dataId, String group, String tenant) throws Throwable { String dataId, String group, String tenant) throws Throwable {
final String groupKey = GroupKey2.getKey(dataId, group, tenant); final String groupKey = GroupKey2.getKey(dataId, group, tenant);
final String md5 = ConfigService.getContentMd5(groupKey); final String md5 = ConfigService.getContentMd5(groupKey);
MetricsMonitor.getConfigMonitor().incrementAndGet();
return logClientRequest("get", pjp, request, response, dataId, group, tenant, md5); return logClientRequest("get", pjp, request, response, dataId, group, tenant, md5);
} }

View File

@ -252,7 +252,7 @@ public class ConfigController {
inner.doPollingConfig(request, response, clientMd5Map, probeModify.length()); inner.doPollingConfig(request, response, clientMd5Map, probeModify.length());
} }
/* /**
* 订阅改配置的客户端信息 * 订阅改配置的客户端信息
*/ */
@RequestMapping(value = "/listener", method = RequestMethod.GET) @RequestMapping(value = "/listener", method = RequestMethod.GET)

View File

@ -60,7 +60,7 @@ public class ConfigServletInner {
private static final int TRY_GET_LOCK_TIMES = 9; private static final int TRY_GET_LOCK_TIMES = 9;
private static final int START_LONGPULLING_VERSION_NUM = 204; private static final int START_LONGPOLLING_VERSION_NUM = 204;
/** /**
* 轮询接口 * 轮询接口
@ -70,8 +70,8 @@ public class ConfigServletInner {
throws IOException, ServletException { throws IOException, ServletException {
// 长轮询 // 长轮询
if (LongPollingService.isSupportLongPulling(request)) { if (LongPollingService.isSupportLongPolling(request)) {
longPollingService.addLongPullingClient(request, response, clientMd5Map, probeRequestSize); longPollingService.addLongPollingClient(request, response, clientMd5Map, probeRequestSize);
return HttpServletResponse.SC_OK + ""; return HttpServletResponse.SC_OK + "";
} }
@ -91,7 +91,7 @@ public class ConfigServletInner {
/** /**
* 2.0.4版本以前, 返回值放入header中 * 2.0.4版本以前, 返回值放入header中
*/ */
if (versionNum < START_LONGPULLING_VERSION_NUM) { if (versionNum < START_LONGPOLLING_VERSION_NUM) {
response.addHeader(Constants.PROBE_MODIFY_RESPONSE, oldResult); response.addHeader(Constants.PROBE_MODIFY_RESPONSE, oldResult);
response.addHeader(Constants.PROBE_MODIFY_RESPONSE_NEW, newResult); response.addHeader(Constants.PROBE_MODIFY_RESPONSE_NEW, newResult);
} else { } else {

View File

@ -64,17 +64,17 @@ public class HealthController {
} else if (dbStatus.contains(heathWarnStr) && ServerListService.isAddressServerHealth() && ServerListService } else if (dbStatus.contains(heathWarnStr) && ServerListService.isAddressServerHealth() && ServerListService
.isInIpList()) { .isInIpList()) {
sb.append("WARN:"); sb.append("WARN:");
sb.append("从数据库 ").append(dbStatus.split(":")[1]).append(" down. "); sb.append("slave db (").append(dbStatus.split(":")[1]).append(") down. ");
} else { } else {
sb.append("DOWN:"); sb.append("DOWN:");
if (dbStatus.contains(heathDownStr)) { if (dbStatus.contains(heathDownStr)) {
sb.append("主数据库 ").append(dbStatus.split(":")[1]).append(" down. "); sb.append("master db (").append(dbStatus.split(":")[1]).append(") down. ");
} }
if (!ServerListService.isAddressServerHealth()) { if (!ServerListService.isAddressServerHealth()) {
sb.append("地址服务器 down. "); sb.append("address server down. ");
} }
if (!ServerListService.isInIpList()) { if (!ServerListService.isInIpList()) {
sb.append("server ").append(LOCAL_IP).append(" 不在地址服务器的IP列表中. "); sb.append("server ip ").append(LOCAL_IP).append(" is not in the serverList of address server. ");
} }
} }

View File

@ -35,7 +35,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* Config longpulling * Config longpolling
* *
* @author Nacos * @author Nacos
*/ */
@ -48,7 +48,7 @@ public class ListenerController {
@Autowired @Autowired
public ListenerController(ConfigSubService configSubService) {this.configSubService = configSubService;} public ListenerController(ConfigSubService configSubService) {this.configSubService = configSubService;}
/* /**
* 获取客户端订阅配置信息 * 获取客户端订阅配置信息
*/ */
@RequestMapping(method = RequestMethod.GET) @RequestMapping(method = RequestMethod.GET)

View File

@ -15,9 +15,13 @@
*/ */
package com.alibaba.nacos.config.server.controller; package com.alibaba.nacos.config.server.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.service.PersistService; import com.alibaba.nacos.config.server.service.PersistService;
import com.alibaba.nacos.config.server.service.dump.DumpService; import com.alibaba.nacos.config.server.service.dump.DumpService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -26,9 +30,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/** /**
* 管理控制器 * 管理控制器
* *
@ -50,7 +51,9 @@ public class OpsController {
this.dumpService = dumpService; this.dumpService = dumpService;
} }
// ops call /**
* ops call
*/
@RequestMapping(value = "/localCache", method = RequestMethod.POST) @RequestMapping(value = "/localCache", method = RequestMethod.POST)
@ResponseBody @ResponseBody
public String updateLocalCacheFromStore(HttpServletRequest request, HttpServletResponse respons) { public String updateLocalCacheFromStore(HttpServletRequest request, HttpServletResponse respons) {

View File

@ -15,6 +15,9 @@
*/ */
package com.alibaba.nacos.config.server.exception; package com.alibaba.nacos.config.server.exception;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
@ -37,6 +40,7 @@ public class GlobalExceptionHandler {
*/ */
@ExceptionHandler(IllegalArgumentException.class) @ExceptionHandler(IllegalArgumentException.class)
public void handleIllegalArgumentException(HttpServletResponse response, Exception ex) throws IOException { public void handleIllegalArgumentException(HttpServletResponse response, Exception ex) throws IOException {
MetricsMonitor.getIllegalArgumentException().increment();
response.setStatus(400); response.setStatus(400);
if (ex.getMessage() != null) { if (ex.getMessage() != null) {
response.getWriter().println(ex.getMessage()); response.getWriter().println(ex.getMessage());
@ -52,6 +56,7 @@ public class GlobalExceptionHandler {
*/ */
@ExceptionHandler(NacosException.class) @ExceptionHandler(NacosException.class)
public void handleNacosException(HttpServletResponse response, NacosException ex) throws IOException { public void handleNacosException(HttpServletResponse response, NacosException ex) throws IOException {
MetricsMonitor.getNacosException().increment();
response.setStatus(ex.getErrCode()); response.setStatus(ex.getErrCode());
if (ex.getErrMsg() != null) { if (ex.getErrMsg() != null) {
response.getWriter().println(ex.getErrMsg()); response.getWriter().println(ex.getErrMsg());
@ -60,4 +65,15 @@ public class GlobalExceptionHandler {
} }
} }
/**
* For DataAccessException
*
* @throws DataAccessException
*/
@ExceptionHandler(DataAccessException.class)
public void handleDataAccessException(HttpServletResponse response, DataAccessException ex) throws DataAccessException {
MetricsMonitor.getDbException().increment();
throw new CannotGetJdbcConnectionException(ex.getMessage());
}
} }

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.config.server.manager; package com.alibaba.nacos.config.server.manager;
import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.LogUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -51,6 +52,7 @@ public final class TaskManager implements TaskManagerMBean {
private String name; private String name;
class ProcessRunnable implements Runnable { class ProcessRunnable implements Runnable {
public void run() { public void run() {
@ -140,6 +142,7 @@ public final class TaskManager implements TaskManagerMBean {
this.lock.lock(); this.lock.lock();
try { try {
this.tasks.remove(type); this.tasks.remove(type);
MetricsMonitor.getDumpTaskMonitor().set(tasks.size());
} finally { } finally {
this.lock.unlock(); this.lock.unlock();
} }
@ -150,12 +153,12 @@ public final class TaskManager implements TaskManagerMBean {
* *
* @param type * @param type
* @param task * @param task
* @param previousTask
*/ */
public void addTask(String type, AbstractTask task) { public void addTask(String type, AbstractTask task) {
this.lock.lock(); this.lock.lock();
try { try {
AbstractTask oldTask = tasks.put(type, task); AbstractTask oldTask = tasks.put(type, task);
MetricsMonitor.getDumpTaskMonitor().set(tasks.size());
if (null != oldTask) { if (null != oldTask) {
task.merge(oldTask); task.merge(oldTask);
} }
@ -181,6 +184,7 @@ public final class TaskManager implements TaskManagerMBean {
} }
// 先将任务从任务Map中删除 // 先将任务从任务Map中删除
this.tasks.remove(entry.getKey()); this.tasks.remove(entry.getKey());
MetricsMonitor.getDumpTaskMonitor().set(tasks.size());
} }
} finally { } finally {
this.lock.unlock(); this.lock.unlock();

View File

@ -28,6 +28,6 @@ public interface TaskManagerMBean {
* *
* @return info * @return info
*/ */
public String getTaskInfos(); String getTaskInfos();
} }

View File

@ -0,0 +1,42 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.config.server.model;
/**
* user info
*
* @author wfnuser
*/
public class User {
private String username;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}

View File

@ -20,10 +20,12 @@ import com.alibaba.nacos.config.server.service.ConfigService;
import com.alibaba.nacos.config.server.service.TimerTaskService; import com.alibaba.nacos.config.server.service.TimerTaskService;
import com.alibaba.nacos.config.server.service.notify.AsyncNotifyService; import com.alibaba.nacos.config.server.service.notify.AsyncNotifyService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static com.alibaba.nacos.config.server.utils.LogUtil.memoryLog; import static com.alibaba.nacos.config.server.utils.LogUtil.memoryLog;
@ -34,6 +36,7 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.memoryLog;
*/ */
@Service @Service
public class MemoryMonitor { public class MemoryMonitor {
@Autowired @Autowired
public MemoryMonitor(AsyncNotifyService notifySingleService) { public MemoryMonitor(AsyncNotifyService notifySingleService) {
@ -45,9 +48,16 @@ public class MemoryMonitor {
TimerTaskService.scheduleWithFixedDelay(new NotifyTaskQueueMonitorTask(notifySingleService), DELAY_SECONDS, TimerTaskService.scheduleWithFixedDelay(new NotifyTaskQueueMonitorTask(notifySingleService), DELAY_SECONDS,
DELAY_SECONDS, TimeUnit.SECONDS); DELAY_SECONDS, TimeUnit.SECONDS);
} }
static final long DELAY_SECONDS = 10; static final long DELAY_SECONDS = 10;
@Scheduled(cron = "0 0 0 * * ?")
public void clear() {
MetricsMonitor.getConfigMonitor().set(0);
MetricsMonitor.getPublishMonitor().set(0);
}
} }
class PrintGetConfigResponeTask implements Runnable { class PrintGetConfigResponeTask implements Runnable {
@ -58,6 +68,7 @@ class PrintGetConfigResponeTask implements Runnable {
} }
class PrintMemoryTask implements Runnable { class PrintMemoryTask implements Runnable {
@Override @Override
public void run() { public void run() {
int groupCount = ConfigService.groupCount(); int groupCount = ConfigService.groupCount();
@ -65,11 +76,14 @@ class PrintMemoryTask implements Runnable {
long subCount = ClientTrackService.subscriberCount(); long subCount = ClientTrackService.subscriberCount();
memoryLog.info("groupCount={}, subscriberClientCount={}, subscriberCount={}", groupCount, subClientCount, memoryLog.info("groupCount={}, subscriberClientCount={}, subscriberCount={}", groupCount, subClientCount,
subCount); subCount);
MetricsMonitor.getConfigCountMonitor().set(groupCount);
} }
} }
class NotifyTaskQueueMonitorTask implements Runnable { class NotifyTaskQueueMonitorTask implements Runnable {
final private AsyncNotifyService notifySingleService; final private AsyncNotifyService notifySingleService;
private AtomicInteger notifyTask = new AtomicInteger();
NotifyTaskQueueMonitorTask(AsyncNotifyService notifySingleService) { NotifyTaskQueueMonitorTask(AsyncNotifyService notifySingleService) {
this.notifySingleService = notifySingleService; this.notifySingleService = notifySingleService;
@ -77,16 +91,10 @@ class NotifyTaskQueueMonitorTask implements Runnable {
@Override @Override
public void run() { public void run() {
int size = ((ScheduledThreadPoolExecutor)notifySingleService.getExecutor()).getQueue().size();
memoryLog.info("notifySingleServiceThreadPool-{}, toNotifyTaskSize={}", memoryLog.info("notifySingleServiceThreadPool-{}, toNotifyTaskSize={}",
new Object[] {((ScheduledThreadPoolExecutor)notifySingleService.getExecutor()).getClass().getName(), new Object[] {((ScheduledThreadPoolExecutor)notifySingleService.getExecutor()).getClass().getName(),
((ScheduledThreadPoolExecutor)notifySingleService.getExecutor()).getQueue().size()}); size});
MetricsMonitor.getNotifyTaskMonitor().set(size);
// for(Map.Entry<String, Executor> entry: notifySingleService.getExecutors().entrySet()) {
// ThreadPoolExecutor pool = (ThreadPoolExecutor) entry.getValue();
// String target = entry.getKey();
// memoryLog.info("notifySingleServiceThreadPool-{}, toNotifyTaskSize={}",
// new Object[] { target, pool.getQueue().size() });
// }
} }
} }

View File

@ -0,0 +1,124 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.config.server.monitor;
import io.micrometer.core.instrument.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Metrics Monitor
*
* @author Nacos
*/
public class MetricsMonitor {
private static AtomicInteger getConfig = new AtomicInteger();
private static AtomicInteger publish = new AtomicInteger();
private static AtomicInteger longPolling = new AtomicInteger();
private static AtomicInteger configCount = new AtomicInteger();
private static AtomicInteger notifyTask = new AtomicInteger();
private static AtomicInteger dumpTask = new AtomicInteger();
static {
List<Tag> tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "getConfig"));
Metrics.gauge("nacos_monitor", tags, getConfig);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "publish"));
Metrics.gauge("nacos_monitor", tags, publish);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "longPolling"));
Metrics.gauge("nacos_monitor", tags, longPolling);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "configCount"));
Metrics.gauge("nacos_monitor", tags, configCount);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "notifyTask"));
Metrics.gauge("nacos_monitor", tags, notifyTask);
tags = new ArrayList<Tag>();
tags.add(new ImmutableTag("module", "config"));
tags.add(new ImmutableTag("name", "dumpTask"));
Metrics.gauge("nacos_monitor", tags, dumpTask);
}
public static AtomicInteger getConfigMonitor() {
return getConfig;
}
public static AtomicInteger getPublishMonitor() {
return publish;
}
public static AtomicInteger getLongPollingMonitor() {
return longPolling;
}
public static AtomicInteger getConfigCountMonitor() {
return configCount;
}
public static AtomicInteger getNotifyTaskMonitor() {
return notifyTask;
}
public static AtomicInteger getDumpTaskMonitor() {
return dumpTask;
}
public static Timer getNotifyRtTimer() {
return Metrics.timer("nacos_timer",
"module", "config", "name", "notifyRt");
}
public static Counter getIllegalArgumentException() {
return Metrics.counter("nacos_exception",
"module", "config", "name", "illegalArgument");
}
public static Counter getNacosException() {
return Metrics.counter("nacos_exception",
"module", "config", "name", "nacos");
}
public static Counter getDbException() {
return Metrics.counter("nacos_exception",
"module", "config", "name", "db");
}
public static Counter getConfigNotifyException() {
return Metrics.counter("nacos_exception",
"module", "config", "name", "configNotify");
}
public static Counter getUnhealthException() {
return Metrics.counter("nacos_exception",
"module", "config", "name", "unhealth");
}
}

View File

@ -15,7 +15,19 @@
*/ */
package com.alibaba.nacos.config.server.service; package com.alibaba.nacos.config.server.service;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import com.alibaba.nacos.config.server.utils.PropertyUtil; import com.alibaba.nacos.config.server.utils.PropertyUtil;
import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.lang3.math.NumberUtils;
@ -28,15 +40,6 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.alibaba.nacos.common.util.SystemUtils.STANDALONE_MODE; import static com.alibaba.nacos.common.util.SystemUtils.STANDALONE_MODE;
import static com.alibaba.nacos.config.server.service.PersistService.CONFIG_INFO4BETA_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.PersistService.CONFIG_INFO4BETA_ROW_MAPPER;
import static com.alibaba.nacos.config.server.utils.LogUtil.defaultLog; import static com.alibaba.nacos.config.server.utils.LogUtil.defaultLog;
@ -51,9 +54,6 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
public class BasicDataSourceServiceImpl implements DataSourceService { public class BasicDataSourceServiceImpl implements DataSourceService {
private static final String JDBC_DRIVER_NAME = "com.mysql.jdbc.Driver"; private static final String JDBC_DRIVER_NAME = "com.mysql.jdbc.Driver";
@Autowired
private PropertyUtil propertyUtil;
/** /**
* JDBC执行超时时间, 单位秒 * JDBC执行超时时间, 单位秒
*/ */
@ -109,7 +109,7 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
* 事务的超时时间需要与普通操作区分开 * 事务的超时时间需要与普通操作区分开
*/ */
tjt.setTimeout(TRANSACTION_QUERY_TIMEOUT); tjt.setTimeout(TRANSACTION_QUERY_TIMEOUT);
if (!STANDALONE_MODE || propertyUtil.isStandaloneUseMysql()) { if (!STANDALONE_MODE || PropertyUtil.isStandaloneUseMysql()) {
try { try {
reload(); reload();
} catch (IOException e) { } catch (IOException e) {
@ -124,6 +124,7 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
} }
} }
@Override
public synchronized void reload() throws IOException { public synchronized void reload() throws IOException {
List<BasicDataSource> dblist = new ArrayList<BasicDataSource>(); List<BasicDataSource> dblist = new ArrayList<BasicDataSource>();
try { try {
@ -201,6 +202,7 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
} }
} }
@Override
public boolean checkMasterWritable() { public boolean checkMasterWritable() {
testMasterWritableJT.setDataSource(jt.getDataSource()); testMasterWritableJT.setDataSource(jt.getDataSource());
@ -224,14 +226,17 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
} }
@Override
public JdbcTemplate getJdbcTemplate() { public JdbcTemplate getJdbcTemplate() {
return this.jt; return this.jt;
} }
@Override
public TransactionTemplate getTransactionTemplate() { public TransactionTemplate getTransactionTemplate() {
return this.tjt; return this.tjt;
} }
@Override
public String getCurrentDBUrl() { public String getCurrentDBUrl() {
DataSource ds = this.jt.getDataSource(); DataSource ds = this.jt.getDataSource();
if (ds == null) { if (ds == null) {
@ -241,6 +246,7 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
return bds.getUrl(); return bds.getUrl();
} }
@Override
public String getHealth() { public String getHealth() {
for (int i = 0; i < isHealthList.size(); i++) { for (int i = 0; i < isHealthList.size(); i++) {
if (!isHealthList.get(i)) { if (!isHealthList.get(i)) {
@ -276,6 +282,7 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
} }
class SelectMasterTask implements Runnable { class SelectMasterTask implements Runnable {
@Override
public void run() { public void run() {
defaultLog.info("check master db."); defaultLog.info("check master db.");
boolean isFound = false; boolean isFound = false;
@ -303,12 +310,14 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
if (!isFound) { if (!isFound) {
fatalLog.error("[master-db] master db not found."); fatalLog.error("[master-db] master db not found.");
MetricsMonitor.getDbException().increment();
} }
} }
} }
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule") @SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
class CheckDBHealthTask implements Runnable { class CheckDBHealthTask implements Runnable {
@Override
public void run() { public void run() {
defaultLog.info("check db health."); defaultLog.info("check db health.");
String sql = "SELECT * FROM config_info_beta WHERE id = 1"; String sql = "SELECT * FROM config_info_beta WHERE id = 1";
@ -325,6 +334,8 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
fatalLog.error("[db-error] slave db {} down.", getIpFromUrl(dataSourceList.get(i).getUrl())); fatalLog.error("[db-error] slave db {} down.", getIpFromUrl(dataSourceList.get(i).getUrl()));
} }
isHealthList.set(i, Boolean.FALSE); isHealthList.set(i, Boolean.FALSE);
MetricsMonitor.getDbException().increment();
} }
} }
} }

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.config.server.service; package com.alibaba.nacos.config.server.service;
import com.alibaba.nacos.config.server.model.SampleResult; import com.alibaba.nacos.config.server.model.SampleResult;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.utils.GroupKey; import com.alibaba.nacos.config.server.utils.GroupKey;
import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.LogUtil;
import com.alibaba.nacos.config.server.utils.MD5Util; import com.alibaba.nacos.config.server.utils.MD5Util;
@ -65,7 +66,7 @@ public class LongPollingService extends AbstractEventListener {
} }
public Map<String, String> getClientSubConfigInfo(String clientIp) { public Map<String, String> getClientSubConfigInfo(String clientIp) {
ClientLongPulling record = getClientPollingRecord(clientIp); ClientLongPolling record = getClientPollingRecord(clientIp);
if (record == null) { if (record == null) {
return Collections.<String, String>emptyMap(); return Collections.<String, String>emptyMap();
@ -79,9 +80,9 @@ public class LongPollingService extends AbstractEventListener {
SampleResult sampleResult = new SampleResult(); SampleResult sampleResult = new SampleResult();
Map<String, String> lisentersGroupkeyStatus = new HashMap<String, String>(50); Map<String, String> lisentersGroupkeyStatus = new HashMap<String, String>(50);
for (ClientLongPulling clientLongPulling : allSubs) { for (ClientLongPolling clientLongPolling : allSubs) {
if (clientLongPulling.clientMd5Map.containsKey(groupKey)) { if (clientLongPolling.clientMd5Map.containsKey(groupKey)) {
lisentersGroupkeyStatus.put(clientLongPulling.ip, clientLongPulling.clientMd5Map.get(groupKey)); lisentersGroupkeyStatus.put(clientLongPolling.ip, clientLongPolling.clientMd5Map.get(groupKey));
} }
} }
sampleResult.setLisentersGroupkeyStatus(lisentersGroupkeyStatus); sampleResult.setLisentersGroupkeyStatus(lisentersGroupkeyStatus);
@ -92,11 +93,11 @@ public class LongPollingService extends AbstractEventListener {
SampleResult sampleResult = new SampleResult(); SampleResult sampleResult = new SampleResult();
Map<String, String> lisentersGroupkeyStatus = new HashMap<String, String>(50); Map<String, String> lisentersGroupkeyStatus = new HashMap<String, String>(50);
for (ClientLongPulling clientLongPulling : allSubs) { for (ClientLongPolling clientLongPolling : allSubs) {
if (clientLongPulling.ip.equals(clientIp)) { if (clientLongPolling.ip.equals(clientIp)) {
// 一个ip可能有多个监听 // 一个ip可能有多个监听
if (!lisentersGroupkeyStatus.equals(clientLongPulling.clientMd5Map)) { if (!lisentersGroupkeyStatus.equals(clientLongPolling.clientMd5Map)) {
lisentersGroupkeyStatus.putAll(clientLongPulling.clientMd5Map); lisentersGroupkeyStatus.putAll(clientLongPolling.clientMd5Map);
} }
} }
} }
@ -128,18 +129,18 @@ public class LongPollingService extends AbstractEventListener {
return null; return null;
} }
HashMap<String, Set<String>> app2Groupkeys = new HashMap<String, Set<String>>(50); HashMap<String, Set<String>> app2Groupkeys = new HashMap<String, Set<String>>(50);
for (ClientLongPulling clientLongPulling : allSubs) { for (ClientLongPolling clientLongPolling : allSubs) {
if (StringUtils.isEmpty(clientLongPulling.appName) || "unknown".equalsIgnoreCase( if (StringUtils.isEmpty(clientLongPolling.appName) || "unknown".equalsIgnoreCase(
clientLongPulling.appName)) { clientLongPolling.appName)) {
continue; continue;
} }
Set<String> appSubscribeConfigs = app2Groupkeys.get(clientLongPulling.appName); Set<String> appSubscribeConfigs = app2Groupkeys.get(clientLongPolling.appName);
Set<String> clientSubscribeConfigs = clientLongPulling.clientMd5Map.keySet(); Set<String> clientSubscribeConfigs = clientLongPolling.clientMd5Map.keySet();
if (appSubscribeConfigs == null) { if (appSubscribeConfigs == null) {
appSubscribeConfigs = new HashSet<String>(clientSubscribeConfigs.size()); appSubscribeConfigs = new HashSet<String>(clientSubscribeConfigs.size());
} }
appSubscribeConfigs.addAll(clientSubscribeConfigs); appSubscribeConfigs.addAll(clientSubscribeConfigs);
app2Groupkeys.put(clientLongPulling.appName, appSubscribeConfigs); app2Groupkeys.put(clientLongPolling.appName, appSubscribeConfigs);
} }
return app2Groupkeys; return app2Groupkeys;
@ -187,27 +188,27 @@ public class LongPollingService extends AbstractEventListener {
return sampleResult; return sampleResult;
} }
private ClientLongPulling getClientPollingRecord(String clientIp) { private ClientLongPolling getClientPollingRecord(String clientIp) {
if (allSubs == null) { if (allSubs == null) {
return null; return null;
} }
for (ClientLongPulling clientLongPulling : allSubs) { for (ClientLongPolling clientLongPolling : allSubs) {
HttpServletRequest request = (HttpServletRequest)clientLongPulling.asyncContext.getRequest(); HttpServletRequest request = (HttpServletRequest) clientLongPolling.asyncContext.getRequest();
if (clientIp.equals(RequestUtil.getRemoteIp(request))) { if (clientIp.equals(RequestUtil.getRemoteIp(request))) {
return clientLongPulling; return clientLongPolling;
} }
} }
return null; return null;
} }
public void addLongPullingClient(HttpServletRequest req, HttpServletResponse rsp, Map<String, String> clientMd5Map, public void addLongPollingClient(HttpServletRequest req, HttpServletResponse rsp, Map<String, String> clientMd5Map,
int probeRequestSize) { int probeRequestSize) {
String str = req.getHeader(LongPollingService.LONG_PULLING_HEADER); String str = req.getHeader(LongPollingService.LONG_POLLING_HEADER);
String noHangUpFlag = req.getHeader(LongPollingService.LONG_PULLING_NO_HANG_UP_HEADER); String noHangUpFlag = req.getHeader(LongPollingService.LONG_POLLING_NO_HANG_UP_HEADER);
String appName = req.getHeader(RequestUtil.CLIENT_APPNAME_HEADER); String appName = req.getHeader(RequestUtil.CLIENT_APPNAME_HEADER);
String tag = req.getHeader("Vipserver-Tag"); String tag = req.getHeader("Vipserver-Tag");
int delayTime = SwitchService.getSwitchInteger(SwitchService.FIXED_DELAY_TIME, 500); int delayTime = SwitchService.getSwitchInteger(SwitchService.FIXED_DELAY_TIME, 500);
@ -241,7 +242,7 @@ public class LongPollingService extends AbstractEventListener {
asyncContext.setTimeout(0L); asyncContext.setTimeout(0L);
scheduler.execute( scheduler.execute(
new ClientLongPulling(asyncContext, clientMd5Map, ip, probeRequestSize, timeout, appName, tag)); new ClientLongPolling(asyncContext, clientMd5Map, ip, probeRequestSize, timeout, appName, tag));
} }
@Override @Override
@ -263,20 +264,20 @@ public class LongPollingService extends AbstractEventListener {
} }
} }
static public boolean isSupportLongPulling(HttpServletRequest req) { static public boolean isSupportLongPolling(HttpServletRequest req) {
return null != req.getHeader(LONG_PULLING_HEADER); return null != req.getHeader(LONG_POLLING_HEADER);
} }
@SuppressWarnings("PMD.ThreadPoolCreationRule") @SuppressWarnings("PMD.ThreadPoolCreationRule")
public LongPollingService() { public LongPollingService() {
allSubs = new ConcurrentLinkedQueue<ClientLongPulling>(); allSubs = new ConcurrentLinkedQueue<ClientLongPolling>();
scheduler = Executors.newScheduledThreadPool(1, new ThreadFactory() { scheduler = Executors.newScheduledThreadPool(1, new ThreadFactory() {
@Override @Override
public Thread newThread(Runnable r) { public Thread newThread(Runnable r) {
Thread t = new Thread(r); Thread t = new Thread(r);
t.setDaemon(true); t.setDaemon(true);
t.setName("com.alibaba.nacos.LongPulling"); t.setName("com.alibaba.nacos.LongPolling");
return t; return t;
} }
}); });
@ -285,15 +286,15 @@ public class LongPollingService extends AbstractEventListener {
// ================= // =================
static public final String LONG_PULLING_HEADER = "Long-Pulling-Timeout"; static public final String LONG_POLLING_HEADER = "Long-Pulling-Timeout";
static public final String LONG_PULLING_NO_HANG_UP_HEADER = "Long-Pulling-Timeout-No-Hangup"; static public final String LONG_POLLING_NO_HANG_UP_HEADER = "Long-Pulling-Timeout-No-Hangup";
final ScheduledExecutorService scheduler; final ScheduledExecutorService scheduler;
/** /**
* 长轮询订阅关系 * 长轮询订阅关系
*/ */
final Queue<ClientLongPulling> allSubs; final Queue<ClientLongPolling> allSubs;
// ================= // =================
@ -302,8 +303,8 @@ public class LongPollingService extends AbstractEventListener {
public void run() { public void run() {
try { try {
ConfigService.getContentBetaMd5(groupKey); ConfigService.getContentBetaMd5(groupKey);
for (Iterator<ClientLongPulling> iter = allSubs.iterator(); iter.hasNext(); ) { for (Iterator<ClientLongPolling> iter = allSubs.iterator(); iter.hasNext(); ) {
ClientLongPulling clientSub = iter.next(); ClientLongPolling clientSub = iter.next();
if (clientSub.clientMd5Map.containsKey(groupKey)) { if (clientSub.clientMd5Map.containsKey(groupKey)) {
// 如果beta发布且不在beta列表直接跳过 // 如果beta发布且不在beta列表直接跳过
if (isBeta && !betaIps.contains(clientSub.ip)) { if (isBeta && !betaIps.contains(clientSub.ip)) {
@ -359,23 +360,24 @@ public class LongPollingService extends AbstractEventListener {
@Override @Override
public void run() { public void run() {
memoryLog.info("[long-pulling] client count " + allSubs.size()); memoryLog.info("[long-pulling] client count " + allSubs.size());
MetricsMonitor.getLongPollingMonitor().set(allSubs.size());
} }
} }
// ================= // =================
class ClientLongPulling implements Runnable { class ClientLongPolling implements Runnable {
@Override @Override
public void run() { public void run() {
asyncTimeoutFuture = scheduler.schedule(new Runnable() { asyncTimeoutFuture = scheduler.schedule(new Runnable() {
public void run() { public void run() {
try { try {
getRetainIps().put(ClientLongPulling.this.ip, System.currentTimeMillis()); getRetainIps().put(ClientLongPolling.this.ip, System.currentTimeMillis());
/** /**
* 删除订阅关系 * 删除订阅关系
*/ */
allSubs.remove(ClientLongPulling.this); allSubs.remove(ClientLongPolling.this);
if (isFixedPolling()) { if (isFixedPolling()) {
LogUtil.clientLog.info("{}|{}|{}|{}|{}|{}", LogUtil.clientLog.info("{}|{}|{}|{}|{}|{}",
@ -400,7 +402,7 @@ public class LongPollingService extends AbstractEventListener {
sendResponse(null); sendResponse(null);
} }
} catch (Throwable t) { } catch (Throwable t) {
LogUtil.defaultLog.error("long pulling error:" + t.getMessage(), t.getCause()); LogUtil.defaultLog.error("long polling error:" + t.getMessage(), t.getCause());
} }
} }
@ -446,7 +448,7 @@ public class LongPollingService extends AbstractEventListener {
} }
} }
ClientLongPulling(AsyncContext ac, Map<String, String> clientMd5Map, String ip, int probeRequestSize, ClientLongPolling(AsyncContext ac, Map<String, String> clientMd5Map, String ip, int probeRequestSize,
long timeoutTime, String appName, String tag) { long timeoutTime, String appName, String tag) {
this.asyncContext = ac; this.asyncContext = ac;
this.clientMd5Map = clientMd5Map; this.clientMd5Map = clientMd5Map;

View File

@ -33,6 +33,7 @@ import java.util.Map.Entry;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import com.alibaba.nacos.config.server.model.*;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
@ -53,19 +54,6 @@ import org.springframework.transaction.TransactionSystemException;
import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import com.alibaba.nacos.config.server.model.ConfigAdvanceInfo;
import com.alibaba.nacos.config.server.model.ConfigAllInfo;
import com.alibaba.nacos.config.server.model.ConfigHistoryInfo;
import com.alibaba.nacos.config.server.model.ConfigInfo;
import com.alibaba.nacos.config.server.model.ConfigInfo4Beta;
import com.alibaba.nacos.config.server.model.ConfigInfo4Tag;
import com.alibaba.nacos.config.server.model.ConfigInfoAggr;
import com.alibaba.nacos.config.server.model.ConfigInfoBase;
import com.alibaba.nacos.config.server.model.ConfigInfoChanged;
import com.alibaba.nacos.config.server.model.ConfigKey;
import com.alibaba.nacos.config.server.model.Page;
import com.alibaba.nacos.config.server.model.SubInfo;
import com.alibaba.nacos.config.server.model.TenantInfo;
import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.LogUtil;
import com.alibaba.nacos.config.server.utils.MD5; import com.alibaba.nacos.config.server.utils.MD5;
import com.alibaba.nacos.config.server.utils.PaginationHelper; import com.alibaba.nacos.config.server.utils.PaginationHelper;
@ -455,6 +443,15 @@ public class PersistService {
} }
} }
static final class UserRowMapper implements RowMapper<User> {
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
return user;
}
}
public synchronized void reload() throws IOException { public synchronized void reload() throws IOException {
this.dataSourceService.reload(); this.dataSourceService.reload();
} }
@ -3113,6 +3110,22 @@ public class PersistService {
} }
} }
public User findUserByUsername(String username) {
String sql = "SELECT username,password FROM users WHERE username=? ";
try {
return this.jt.queryForObject(sql, new Object[] {username}, USER_ROW_MAPPER);
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
} catch (EmptyResultDataAccessException e) {
return null;
} catch (Exception e) {
fatalLog.error("[db-other-error]" + e.getMessage(), e);
throw new RuntimeException(e);
}
}
private List<ConfigInfo> convertDeletedConfig(List<Map<String, Object>> list) { private List<ConfigInfo> convertDeletedConfig(List<Map<String, Object>> list) {
List<ConfigInfo> configs = new ArrayList<ConfigInfo>(); List<ConfigInfo> configs = new ArrayList<ConfigInfo>();
for (Map<String, Object> map : list) { for (Map<String, Object> map : list) {
@ -3265,6 +3278,8 @@ public class PersistService {
static final TenantInfoRowMapper TENANT_INFO_ROW_MAPPER = new TenantInfoRowMapper(); static final TenantInfoRowMapper TENANT_INFO_ROW_MAPPER = new TenantInfoRowMapper();
static final UserRowMapper USER_ROW_MAPPER = new UserRowMapper();
static final ConfigInfoWrapperRowMapper CONFIG_INFO_WRAPPER_ROW_MAPPER = new ConfigInfoWrapperRowMapper(); static final ConfigInfoWrapperRowMapper CONFIG_INFO_WRAPPER_ROW_MAPPER = new ConfigInfoWrapperRowMapper();
static final ConfigKeyRowMapper CONFIG_KEY_ROW_MAPPER = new ConfigKeyRowMapper(); static final ConfigKeyRowMapper CONFIG_KEY_ROW_MAPPER = new ConfigKeyRowMapper();

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.config.server.service; package com.alibaba.nacos.config.server.service;
import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.service.notify.NotifyService; import com.alibaba.nacos.config.server.service.notify.NotifyService;
import com.alibaba.nacos.config.server.service.notify.NotifyService.HttpResult; import com.alibaba.nacos.config.server.service.notify.NotifyService.HttpResult;
import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.LogUtil;
@ -377,6 +378,7 @@ public class ServerListService implements ApplicationListener<WebServerInitializ
serverListUnhealth.add(serverIp); serverListUnhealth.add(serverIp);
} }
defaultLog.error("unhealthIp:{}, unhealthCount:{}", serverIp, failCount); defaultLog.error("unhealthIp:{}, unhealthCount:{}", serverIp, failCount);
MetricsMonitor.getUnhealthException().increment();
} }
} }
@ -391,6 +393,7 @@ public class ServerListService implements ApplicationListener<WebServerInitializ
serverListUnhealth.add(serverIp); serverListUnhealth.add(serverIp);
} }
defaultLog.error("unhealthIp:{}, unhealthCount:{}", serverIp, failCount); defaultLog.error("unhealthIp:{}, unhealthCount:{}", serverIp, failCount);
MetricsMonitor.getUnhealthException().increment();
} }
} }
} }

View File

@ -17,6 +17,7 @@ package com.alibaba.nacos.config.server.service.notify;
import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.service.ConfigDataChangeEvent; import com.alibaba.nacos.config.server.service.ConfigDataChangeEvent;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.service.ServerListService; import com.alibaba.nacos.config.server.service.ServerListService;
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService; import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
import com.alibaba.nacos.config.server.utils.*; import com.alibaba.nacos.config.server.utils.*;
@ -192,6 +193,7 @@ public class AsyncNotifyService extends AbstractEventListener {
ConfigTraceService.NOTIFY_EVENT_ERROR, delayed, ConfigTraceService.NOTIFY_EVENT_ERROR, delayed,
task.target); task.target);
//get delay time and set fail count to the task //get delay time and set fail count to the task
int delay = getDelayTime(task); int delay = getDelayTime(task);
@ -207,6 +209,7 @@ public class AsyncNotifyService extends AbstractEventListener {
new Object[] {task.target, task.getDataId(), new Object[] {task.target, task.getDataId(),
task.getGroup(), task.getLastModified()}); task.getGroup(), task.getLastModified()});
MetricsMonitor.getConfigNotifyException().increment();
} }
HttpClientUtils.closeQuietly(response); HttpClientUtils.closeQuietly(response);
} }
@ -238,6 +241,7 @@ public class AsyncNotifyService extends AbstractEventListener {
new Object[] {task.target, task.getDataId(), new Object[] {task.target, task.getDataId(),
task.getGroup(), task.getLastModified()}); task.getGroup(), task.getLastModified()});
MetricsMonitor.getConfigNotifyException().increment();
} }
@Override @Override
@ -262,6 +266,7 @@ public class AsyncNotifyService extends AbstractEventListener {
new Object[] {task.target, task.getDataId(), new Object[] {task.target, task.getDataId(),
task.getGroup(), task.getLastModified()}); task.getGroup(), task.getLastModified()});
MetricsMonitor.getConfigNotifyException().increment();
} }
private NotifySingleTask task; private NotifySingleTask task;

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.config.server.service.notify;
import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.manager.AbstractTask; import com.alibaba.nacos.config.server.manager.AbstractTask;
import com.alibaba.nacos.config.server.manager.TaskProcessor; import com.alibaba.nacos.config.server.manager.TaskProcessor;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.service.ServerListService; import com.alibaba.nacos.config.server.service.ServerListService;
import com.alibaba.nacos.config.server.service.notify.NotifyService.HttpResult; import com.alibaba.nacos.config.server.service.notify.NotifyService.HttpResult;
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService; import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
@ -29,6 +30,7 @@ import org.slf4j.LoggerFactory;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import static com.alibaba.nacos.common.util.SystemUtils.LOCAL_IP; import static com.alibaba.nacos.common.util.SystemUtils.LOCAL_IP;
@ -76,8 +78,12 @@ public class NotifyTaskProcessor implements TaskProcessor {
if (result.code == HttpStatus.SC_OK) { if (result.code == HttpStatus.SC_OK) {
ConfigTraceService.logNotifyEvent(dataId, group, tenant, null, lastModified, LOCAL_IP, ConfigTraceService.logNotifyEvent(dataId, group, tenant, null, lastModified, LOCAL_IP,
ConfigTraceService.NOTIFY_EVENT_OK, delayed, serverIp); ConfigTraceService.NOTIFY_EVENT_OK, delayed, serverIp);
MetricsMonitor.getNotifyRtTimer().record(delayed, TimeUnit.MILLISECONDS);
return true; return true;
} else { } else {
MetricsMonitor.getConfigNotifyException().increment();
log.error("[notify-error] {}, {}, to {}, result {}", new Object[] {dataId, group, log.error("[notify-error] {}, {}, to {}, result {}", new Object[] {dataId, group,
serverIp, result.code}); serverIp, result.code});
ConfigTraceService.logNotifyEvent(dataId, group, tenant, null, lastModified, LOCAL_IP, ConfigTraceService.logNotifyEvent(dataId, group, tenant, null, lastModified, LOCAL_IP,
@ -85,6 +91,7 @@ public class NotifyTaskProcessor implements TaskProcessor {
return false; return false;
} }
} catch (Exception e) { } catch (Exception e) {
MetricsMonitor.getConfigNotifyException().increment();
log.error( log.error(
"[notify-exception] " + dataId + ", " + group + ", to " + serverIp + ", " "[notify-exception] " + dataId + ", " + group + ", to " + serverIp + ", "
+ e.toString()); + e.toString());

View File

@ -15,11 +15,14 @@
*/ */
package com.alibaba.nacos.config.server.service.trace; package com.alibaba.nacos.config.server.service.trace;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.LogUtil;
import com.alibaba.nacos.config.server.utils.MD5; import com.alibaba.nacos.config.server.utils.MD5;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
import static com.alibaba.nacos.common.util.SystemUtils.LOCAL_IP; import static com.alibaba.nacos.common.util.SystemUtils.LOCAL_IP;
/** /**
@ -68,6 +71,7 @@ public class ConfigTraceService {
if (!LogUtil.traceLog.isInfoEnabled()) { if (!LogUtil.traceLog.isInfoEnabled()) {
return; return;
} }
MetricsMonitor.getNotifyRtTimer().record(delayed, TimeUnit.MILLISECONDS);
// 方便tlog切分 // 方便tlog切分
if (StringUtils.isBlank(tenant)) { if (StringUtils.isBlank(tenant)) {
tenant = null; tenant = null;

View File

@ -24,15 +24,40 @@ import javax.servlet.http.HttpServletRequest;
*/ */
public class RequestUtil { public class RequestUtil {
private static final String X_REAL_IP = "X-Real-IP";
private static final String X_FORWARDED_FOR = "X-Forwarded-For";
private static final String X_FORWARDED_FOR_SPLIT_SYMBOL = ",";
public static final String CLIENT_APPNAME_HEADER = "Client-AppName"; public static final String CLIENT_APPNAME_HEADER = "Client-AppName";
/**
* get real client ip
* <p>
* first use X-Forwarded-For header https://zh.wikipedia.org/wiki/X-Forwarded-For
* next nginx X-Real-IP
* last {@link HttpServletRequest#getRemoteAddr()}
*
* @param request {@link HttpServletRequest}
* @return
*/
public static String getRemoteIp(HttpServletRequest request) { public static String getRemoteIp(HttpServletRequest request) {
String nginxHeader = request.getHeader("X-Real-IP"); String xForwardedFor = request.getHeader(X_FORWARDED_FOR);
return (nginxHeader == null) ? request.getRemoteAddr() : nginxHeader; if (!StringUtils.isBlank(xForwardedFor)) {
return xForwardedFor.split(X_FORWARDED_FOR_SPLIT_SYMBOL)[0].trim();
}
String nginxHeader = request.getHeader(X_REAL_IP);
return StringUtils.isBlank(nginxHeader) ? request.getRemoteAddr() : nginxHeader;
} }
/**
* 获取 header 中的客服端应用名称
* <p>
*
* @param request {@link HttpServletRequest}
* @return 可能为 null
*/
public static String getAppName(HttpServletRequest request) { public static String getAppName(HttpServletRequest request) {
return request.getHeader("Client-AppName"); return request.getHeader(CLIENT_APPNAME_HEADER);
} }
} }

View File

@ -177,3 +177,18 @@ CREATE TABLE `tenant_info` (
UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`), UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
KEY `idx_tenant_id` (`tenant_id`) KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';
CREATE TABLE users (
username varchar(50) NOT NULL PRIMARY KEY,
password varchar(500) NOT NULL,
enabled boolean NOT NULL
);
CREATE TABLE roles (
username varchar(50) NOT NULL,
role varchar(50) NOT NULL
);
INSERT INTO users (username, password, enabled) VALUES ('admin', '$2a$10$HxtJtd59imujvbux.i55zOGewhnJiLVXX8D9AETDMV.XtBLDGOXtW', TRUE);
INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN');

View File

@ -173,3 +173,17 @@ CREATE TABLE tenant_info (
CREATE INDEX tenant_info_tenant_id_idx ON tenant_info(tenant_id); CREATE INDEX tenant_info_tenant_id_idx ON tenant_info(tenant_id);
CREATE TABLE users (
username varchar(50) NOT NULL PRIMARY KEY,
password varchar(500) NOT NULL,
enabled boolean NOT NULL
);
CREATE TABLE roles (
username varchar(50) NOT NULL,
role varchar(50) NOT NULL
);
INSERT INTO users (username, password, enabled) VALUES ('admin', '$2a$10$HxtJtd59imujvbux.i55zOGewhnJiLVXX8D9AETDMV.XtBLDGOXtW', TRUE);
INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN');

View File

@ -0,0 +1,61 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.config.server.utils;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
import javax.servlet.http.HttpServletRequest;
import static org.mockito.ArgumentMatchers.eq;
public class RequestUtilTest {
private static final String X_REAL_IP = "X-Real-IP";
private static final String X_FORWARDED_FOR = "X-Forwarded-For";
@Test
public void getRemoteIp() {
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
Mockito.when(request.getRemoteAddr()).thenReturn("127.0.0.1");
Assert.assertEquals(RequestUtil.getRemoteIp(request), "127.0.0.1");
Mockito.when(request.getHeader(eq(X_REAL_IP))).thenReturn("127.0.0.2");
Assert.assertEquals(RequestUtil.getRemoteIp(request), "127.0.0.2");
Mockito.when(request.getHeader(eq(X_FORWARDED_FOR))).thenReturn("127.0.0.3");
Assert.assertEquals(RequestUtil.getRemoteIp(request), "127.0.0.3");
Mockito.when(request.getHeader(eq(X_FORWARDED_FOR))).thenReturn("127.0.0.3, 127.0.0.4");
Assert.assertEquals(RequestUtil.getRemoteIp(request), "127.0.0.3");
Mockito.when(request.getHeader(eq(X_FORWARDED_FOR))).thenReturn("");
Assert.assertEquals(RequestUtil.getRemoteIp(request), "127.0.0.2");
Mockito.when(request.getHeader(eq(X_REAL_IP))).thenReturn("");
Assert.assertEquals(RequestUtil.getRemoteIp(request), "127.0.0.1");
}
@Test
public void getAppName() {
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
Mockito.when(request.getHeader(eq(RequestUtil.CLIENT_APPNAME_HEADER))).thenReturn("test");
Assert.assertEquals(RequestUtil.getAppName(request), "test");
}
}

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>0.7.0</version> <version>0.8.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>nacos-console</artifactId> <artifactId>nacos-console</artifactId>
<!--<packaging>war</packaging>--> <!--<packaging>war</packaging>-->
@ -65,13 +65,33 @@
<artifactId>mockito-core</artifactId> <artifactId>mockito-core</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
<finalName>nacos-server</finalName> <finalName>nacos-server</finalName>
<plugins> <plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
<configuration> <configuration>
<mainClass>com.alibaba.nacos.Nacos</mainClass> <mainClass>com.alibaba.nacos.Nacos</mainClass>
</configuration> </configuration>

View File

@ -19,12 +19,14 @@ package com.alibaba.nacos;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
/** /**
* @author nacos * @author nacos
*/ */
@SpringBootApplication(scanBasePackages = "com.alibaba.nacos") @SpringBootApplication(scanBasePackages = "com.alibaba.nacos")
@ServletComponentScan @ServletComponentScan
@EnableScheduling
public class Nacos { public class Nacos {
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -0,0 +1,107 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.console.config;
import com.alibaba.nacos.console.filter.JwtAuthenticationTokenFilter;
import com.alibaba.nacos.console.security.CustomUserDetailsServiceImpl;
import com.alibaba.nacos.console.security.JwtAuthenticationEntryPoint;
import com.alibaba.nacos.console.utils.JwtTokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* Spring security config
*
* @author Nacos
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String AUTHORIZATION_TOKEN = "access_token";
public static final String SECURITY_IGNORE_URLS_SPILT_CHAR = ",";
@Autowired
private CustomUserDetailsServiceImpl userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Autowired
private JwtTokenUtils tokenProvider;
@Autowired
private Environment env;
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
public void configure(WebSecurity web) {
String ignoreURLs = env.getProperty("nacos.security.ignore.urls", "/**");
for (String ignoreURL : ignoreURLs.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) {
web.ignoring().antMatchers(ignoreURL.trim());
}
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated().and()
// custom token authorize exception handler
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler).and()
// since we use jwt, session is not necessary
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// since we use jwt, csrf is not necessary
.csrf().disable();
http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class);
// disable cache
http.headers().cacheControl();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.console.config.WebSecurityConfig;
import com.alibaba.nacos.config.server.model.RestResult;
import com.alibaba.nacos.console.utils.JwtTokenUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* auth
*
* @author wfnuser
*/
@RestController("auth")
@RequestMapping("/v1/auth")
public class AuthController {
@Autowired
private JwtTokenUtils jwtTokenUtils;
@Autowired
private AuthenticationManager authenticationManager;
/**
* Whether the Nacos is in broken states or not, and cannot recover except by being restarted
*
* @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that
* Nacos is in broken states.
*/
@ResponseBody
@RequestMapping(value = "login", method = RequestMethod.POST)
public RestResult<String> login(HttpServletRequest request, HttpServletResponse response) throws Exception {
String username = request.getParameter("username");
String password = request.getParameter("password");
// 通过用户名和密码创建一个 Authentication 认证对象实现类为 UsernamePasswordAuthenticationToken
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
RestResult<String> rr = new RestResult<String>();
try {
//通过 AuthenticationManager默认实现为ProviderManager的authenticate方法验证 Authentication 对象
Authentication authentication = authenticationManager.authenticate(authenticationToken);
// Authentication 绑定到 SecurityContext
SecurityContextHolder.getContext().setAuthentication(authentication);
//生成Token
String token = jwtTokenUtils.createToken(authentication);
//将Token写入到Http头部
response.addHeader(WebSecurityConfig.AUTHORIZATION_HEADER, "Bearer " + token);
rr.setCode(200);
rr.setData("Bearer " + token);
return rr;
} catch (BadCredentialsException authentication) {
rr.setCode(401);
rr.setMessage("Login failed");
return rr;
}
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.console.filter;
import com.alibaba.nacos.console.config.WebSecurityConfig;
import com.alibaba.nacos.console.utils.JwtTokenUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* jwt auth token filter
*
* @author wfnuser
*/
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
private static final String TOKEN_PREFIX = "Bearer ";
private JwtTokenUtils tokenProvider;
public JwtAuthenticationTokenFilter(JwtTokenUtils tokenProvider) {
this.tokenProvider = tokenProvider;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String jwt = resolveToken(request);
if (!StringUtils.isEmpty(jwt.trim()) && SecurityContextHolder.getContext().getAuthentication() == null) {
if (this.tokenProvider.validateToken(jwt)) {
/**
* get auth info
*/
Authentication authentication = this.tokenProvider.getAuthentication(jwt);
/**
* save user info to securityContext
*/
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
chain.doFilter(request, response);
}
/**
* Get token from header
*/
private String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader(WebSecurityConfig.AUTHORIZATION_HEADER);
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) {
return bearerToken.substring(7, bearerToken.length());
}
String jwt = request.getParameter(WebSecurityConfig.AUTHORIZATION_TOKEN);
if (StringUtils.hasText(jwt)) {
return jwt;
}
return null;
}
}

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.console.model; package com.alibaba.nacos.console.model;
/** /**
* 命名空间 * Namespace
* *
* @author diamond * @author diamond
*/ */
@ -30,7 +30,7 @@ public class Namespace {
private int configCount; private int configCount;
/** /**
* 0 全局配置 1 默认私有命名空间 2 自定义命名空间 * 0 : Global configuration 1 : Default private namespace 2 : Custom namespace
*/ */
private int type; private int type;

View File

@ -0,0 +1,55 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.console.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
/**
* auth provider
*
* @author wfnuser
*/
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private CustomUserDetailsServiceImpl userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = (String) authentication.getPrincipal();
String password = (String) authentication.getCredentials();
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (!password.equals(userDetails.getPassword())) {
return new UsernamePasswordAuthenticationToken(username, null, null);
}
return null;
}
@Override
public boolean supports(Class<?> aClass) {
return aClass.equals(UsernamePasswordAuthenticationToken.class);
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.console.security;
import com.alibaba.nacos.config.server.model.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
/**
* custem user
*
* @author wfnuser
*/
public class CustomUserDetails implements UserDetails {
private User user;
public CustomUserDetails(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO: get authorities
return AuthorityUtils.commaSeparatedStringToAuthorityList("");
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}

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