序
本文主要研究一下 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
doc
- ServerStatusManager