Appearance
单体应用
单体架构:
通俗地讲,“单体应用(monolith application)”就是将应用程序的所有功能都打包成一个独立的单元,可以是JAR、EXE、BIN或其它归档格式。 Spring Boot 完整的部署了一个项目,项目所有功能都在单个项目中做了实现。
单体应用基于SpringBoot进行开发,与微服务应用实现的功能是一样的,但是因为部署和实现方式不同,有如下区别:
单体应用没有网关 - 单机部署无需网关
微服务版中在网关服务实现的过滤器,对应实现是在springboot的拦截器中实现相同的功能。
单体应用只有一个启动模块
微服务各个服务的配置在Nacos中配置,单体应用的配置文件、启动类、配置类则配置在启动模块中。
单体应用暴漏给前端的接口需要代理转接,实现微服务和单体应用使用同一个前端。具体见前端配置。
对于模块间的调用,微服务使用feign在不同的微服务之间调用,而单体应用则直接引入类调用即可。
接口地址校验也有区别
java
/**
* 检查指定接口是否有访问权限
*
* @param path 请求路径
* @param method 请求方法
* @return 是否有权限
*/
public Boolean checkUri(String path, String method) {
// 中间代码省略...
return apiList.parallelStream().distinct().anyMatch(item -> {
String uri = item.getUri();
/*
* 若您确定只使用acuity-boot,而非acuity-cloud,请将def_resource_api表中uri的代理的前缀(/base、/system、/oauth)去除,即可 删除删除删除 if里面的代码!
* 因为脚本数据是基于acuity-cloud配置的,所以uri地址会多一段gateway代理前缀。如
* acuity-cloud 中地址为:/base/baseEmployee/page
* 对应acuity-boot的地址为:/baseEmployee/page
* 其中/base是因为使用了gateway增加的!
*/
if (!StrUtil.startWithAny(uri, "/gateway")) {
uri = StrUtil.subSuf(uri, StrUtil.indexOf(uri, '/', 1));
}
boolean matchUri = PATH_MATCHER.match(StrUtil.trim(uri), StrUtil.trim(path));
log.info("path={}, uri={}, matchUri={}, method={} apiId={}", path, uri, matchUri, item.getRequestMethod(), item.getId());
if (HttpMethod.ALL.name().equalsIgnoreCase(item.getRequestMethod())) {
return matchUri;
}
return matchUri && StrUtil.equalsIgnoreCase(method, item.getRequestMethod());
});
}
/**
* 检查指定接口是否有访问权限
*
* @param path 请求路径
* @param method 请求方法
* @return 是否有权限
*/
public Boolean checkUri(String path, String method) {
// 中间代码省略...
return apiList.parallelStream().distinct().anyMatch(item -> {
String uri = item.getUri();
/*
* 若您确定只使用acuity-boot,而非acuity-cloud,请将def_resource_api表中uri的代理的前缀(/base、/system、/oauth)去除,即可 删除删除删除 if里面的代码!
* 因为脚本数据是基于acuity-cloud配置的,所以uri地址会多一段gateway代理前缀。如
* acuity-cloud 中地址为:/base/baseEmployee/page
* 对应acuity-boot的地址为:/baseEmployee/page
* 其中/base是因为使用了gateway增加的!
*/
if (!StrUtil.startWithAny(uri, "/gateway")) {
uri = StrUtil.subSuf(uri, StrUtil.indexOf(uri, '/', 1));
}
boolean matchUri = PATH_MATCHER.match(StrUtil.trim(uri), StrUtil.trim(path));
log.info("path={}, uri={}, matchUri={}, method={} apiId={}", path, uri, matchUri, item.getRequestMethod(), item.getId());
if (HttpMethod.ALL.name().equalsIgnoreCase(item.getRequestMethod())) {
return matchUri;
}
return matchUri && StrUtil.equalsIgnoreCase(method, item.getRequestMethod());
});
}
java
/**
* 检查指定接口是否有访问权限
*
* @param path 请求路径
* @param method 请求方法
* @return 是否有权限
*/
public Boolean checkUri(String path, String method) {
// 中间代码省略...
return apiList.parallelStream().distinct().anyMatch(item -> {
String uri = item.getUri();
boolean matchUri = PATH_MATCHER.match(StrUtil.trim(uri), StrUtil.trim(path));
log.info("path={}, uri={}, matchUri={}, method={} apiId={}", path, uri, matchUri, item.getRequestMethod(), item.getId());
if (HttpMethod.ALL.name().equalsIgnoreCase(item.getRequestMethod())) {
return matchUri;
}
return matchUri && StrUtil.equalsIgnoreCase(method, item.getRequestMethod());
});
}
/**
* 检查指定接口是否有访问权限
*
* @param path 请求路径
* @param method 请求方法
* @return 是否有权限
*/
public Boolean checkUri(String path, String method) {
// 中间代码省略...
return apiList.parallelStream().distinct().anyMatch(item -> {
String uri = item.getUri();
boolean matchUri = PATH_MATCHER.match(StrUtil.trim(uri), StrUtil.trim(path));
log.info("path={}, uri={}, matchUri={}, method={} apiId={}", path, uri, matchUri, item.getRequestMethod(), item.getId());
if (HttpMethod.ALL.name().equalsIgnoreCase(item.getRequestMethod())) {
return matchUri;
}
return matchUri && StrUtil.equalsIgnoreCase(method, item.getRequestMethod());
});
}
- 初始化数据源的实现也有所区别
java
// acuity-boot 项目GeneratorController位于acuity-boot-server
@ResponseBody
@ApiOperation(value = "查询在线服务的前缀")
@GetMapping("/gateway/findOnlineServicePrefix")
public R<Map<String, String>> findOnlineServicePrefix() {
Map<String, String> map = MapUtil.newHashMap();
map.put(application, "base");
return R.success(map);
}
// acuity-boot 项目GeneratorController位于acuity-boot-server
@ResponseBody
@ApiOperation(value = "查询在线服务的前缀")
@GetMapping("/gateway/findOnlineServicePrefix")
public R<Map<String, String>> findOnlineServicePrefix() {
Map<String, String> map = MapUtil.newHashMap();
map.put(application, "base");
return R.success(map);
}
java
// acuity-cloud 项目GeneratorController位于acuity-gateway-server
@ResponseBody
@ApiOperation(value = "查询在线服务的前缀")
@GetMapping("/gateway/findOnlineServicePrefix")
public R<Map<String, String>> findOnlineServicePrefix() {
List<String> services = discoveryClient.getServices();
Map<String, String> map = MapUtil.newHashMap();
services.forEach(service ->
gatewayProperties.getRoutes().forEach(route -> {
if (StrUtil.equalsIgnoreCase(service, route.getUri().getHost())) {
if (CollUtil.isEmpty(route.getPredicates())) {
return;
}
PredicateDefinition predicateDefinition = route.getPredicates().get(0);
predicateDefinition.getArgs().forEach((k, v) -> {
map.put(service, StrUtil.subBetween(v, "/", "/**"));
});
}
})
);
return R.success(map);
}
// acuity-cloud 项目GeneratorController位于acuity-gateway-server
@ResponseBody
@ApiOperation(value = "查询在线服务的前缀")
@GetMapping("/gateway/findOnlineServicePrefix")
public R<Map<String, String>> findOnlineServicePrefix() {
List<String> services = discoveryClient.getServices();
Map<String, String> map = MapUtil.newHashMap();
services.forEach(service ->
gatewayProperties.getRoutes().forEach(route -> {
if (StrUtil.equalsIgnoreCase(service, route.getUri().getHost())) {
if (CollUtil.isEmpty(route.getPredicates())) {
return;
}
PredicateDefinition predicateDefinition = route.getPredicates().get(0);
predicateDefinition.getArgs().forEach((k, v) -> {
map.put(service, StrUtil.subBetween(v, "/", "/**"));
});
}
})
);
return R.success(map);
}