序
本文主要研究一下nacos的ServerStatusManager
ServerStatusManager
nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerStatusManager.java
@Service
public class ServerStatusManager {
@Resource(name = "consistencyDelegate")
private ConsistencyService consistencyService;
@Autowired
private SwitchDomain switchDomain;
private ServerStatus serverStatus = ServerStatus.STARTING;
@PostConstruct
public void init() {
GlobalExecutor.registerServerStatusUpdater(new ServerStatusUpdater());
}
private void refreshServerStatus() {
if (StringUtils.isNotBlank(switchDomain.getOverriddenServerStatus())) {
serverStatus = ServerStatus.valueOf(switchDomain.getOverriddenServerStatus());
return;
}
if (consistencyService.isAvailable()) {
serverStatus = ServerStatus.UP;
} else {
serverStatus = ServerStatus.DOWN;
}
}
public ServerStatus getServerStatus() {
return serverStatus;
}
public class ServerStatusUpdater implements Runnable {
@Override
public void run() {
refreshServerStatus();
}
}
}
- ServerStatusManager的init方法注册了ServerStatusUpdater,它实现了Runnable接口,其run方法执行refreshServerStatus;refreshServerStatus会判断consistencyService是否是available,如果是更新serverStatus为ServerStatus.UP,否则为ServerStatus.DOWN
ServerStatus
nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerStatus.java
public enum ServerStatus {
/**
* server is up and ready for request
*/
UP,
/**
* server is out of service, something abnormal happened
*/
DOWN,
/**
* server is preparing itself for request, usually 'UP' is the next status
*/
STARTING,
/**
* server is manually paused
*/
PAUSED,
/**
* only write operation is permitted.
*/
WRITE_ONLY,
/**
* only read operation is permitted.
*/
READ_ONLY
}
- ServerStatus有UP、DOWN、STARTING、PAUSED、WRITE_ONLY、READ_ONLY这几种状态
TrafficReviseFilter
nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/web/TrafficReviseFilter.java
public class TrafficReviseFilter implements Filter {
@Autowired
private ServerStatusManager serverStatusManager;
@Autowired
private SwitchDomain switchDomain;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
// request limit if exist:
String urlString = req.getRequestURI() + "?" + req.getQueryString();
Map<String, Integer> limitedUrlMap = switchDomain.getLimitedUrlMap();
if (limitedUrlMap != null && limitedUrlMap.size() > 0) {
for (Map.Entry<String, Integer> entry : limitedUrlMap.entrySet()) {
String limitedUrl = entry.getKey();
if (StringUtils.startsWith(urlString, limitedUrl)) {
resp.setStatus(entry.getValue());
return;
}
}
}
// if server is UP:
if (serverStatusManager.getServerStatus() == ServerStatus.UP) {
filterChain.doFilter(req, resp);
return;
}
// requests from peer server should be let pass:
String agent = req.getHeader("Client-Version");
if (StringUtils.isBlank(agent)) {
agent = req.getHeader("User-Agent");
}
if (StringUtils.startsWith(agent, UtilsAndCommons.NACOS_SERVER_HEADER)) {
filterChain.doFilter(req, resp);
return;
}
// write operation should be let pass in WRITE_ONLY status:
if (serverStatusManager.getServerStatus() == ServerStatus.WRITE_ONLY && !HttpMethod.GET.equals(req.getMethod())) {
filterChain.doFilter(req, resp);
return;
}
// read operation should be let pass in READ_ONLY status:
if (serverStatusManager.getServerStatus() == ServerStatus.READ_ONLY && HttpMethod.GET.equals(req.getMethod())) {
filterChain.doFilter(req, resp);
return;
}
resp.getWriter().write("server is " + serverStatusManager.getServerStatus().name() + " now, please try again later!");
resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
}
}
- TrafficReviseFilter会根据status及httpMethod进行读写路由,路由的不到的返回HttpServletResponse.SC_SERVICE_UNAVAILABLE
小结
ServerStatusManager的init方法注册了ServerStatusUpdater,它实现了Runnable接口,其run方法执行refreshServerStatus;refreshServerStatus会判断consistencyService是否是available,如果是更新serverStatus为ServerStatus.UP,否则为ServerStatus.DOWN