Spring Boot整合Nacos与Gateway实现前后端分离微服务
架构选择nacos作为服务注册,GateWay作为网关两者都是ali。那nacos咱们都知道可作为配置中心来使用且可动态,那做一个动态路由我觉得还是有些必要性的,不至于每次增加路由都要重新部署服务。
Spring Boot整合Gateway与阿里系微服务集成Maven配置如下:
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”>
一、代码整合
@Data
@Component
@ConfigurationProperties(prefix = “broad.dynamic.route”)//yml配置信息,下文给出
@ConditionalOnBean(DynamicRouteConfiguration.class)
public class DynamicRouteProperties {
/**
* nacos 配置管理 dataId
*/
private String dataId;
/**
* nacos 配置管理 group
*/
private String group;
/**
* nacos 服务地址
*/
private String ipAddr;
/**
* 启动动态路由的标志,默认关闭
*/
private boolean enabled = false;
}
DynamicRouteConfiguration:
@Configuration
@ConditionalOnProperty(name = “broad.dynamic.route.enabled”, matchIfMissing = true)
public class DynamicRouteConfiguration implements ApplicationEventPublisherAware {
Logger log= LoggerFactory.getLogger(DynamicRouteConfiguration.class);
//namespace名称
private final static String NAMESPACE=”8359a8d9-03ab-4574-9627-9456351c0c01″;
//nacos账号密码
private final static String USERNAME_PASSWORD=”nacos”;
//截取字符
private final static String REPLACE=”routes:”;
private DynamicRouteProperties bean;
private RouteDefinitionWriter writer;
private ApplicationEventPublisher publisher;
public DynamicRouteConfiguration(DynamicRouteProperties bean, RouteDefinitionWriter writer, ApplicationEventPublisher publisher) {
this.bean = bean;
this.writer = writer;
this.publisher = publisher;
}
@PostConstruct
private void init() {
Assert.notNull(bean.getDataId(), “broad.dynamic.route.dataId null异常”);
Assert.notNull(bean.getGroup(), “broad.dynamic.route.group is null异常”);
Assert.notNull(bean.getIpAddr(), “broad.dynamic.route.ipAddr is null异常”);
dynamicRouteByNacosListener();
}
private void dynamicRouteByNacosListener() {
try {
Properties properties = new Properties();
properties.put(PropertyKeyConst.NAMESPACE, NAMESPACE);
properties.put(PropertyKeyConst.SERVER_ADDR, bean.getIpAddr());
properties.put(“username”,USERNAME_PASSWORD);
properties.put(“password”,USERNAME_PASSWORD);
ConfigService configService = NacosFactory.createConfigService(properties);
String content = configService.getConfigAndSignListener(
bean.getDataId(),
bean.getGroup(),
5000,
new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
updateConfig(configInfo);
}
});
updateConfig(content);
} catch (NacosException e) {
log.error(“nacos 获取动态路由配置和监听异常”, e);
}
}
private void updateConfig(String content) {
String contentReally=replaceContext(content);
log.info(“nacos 动态路由更新: {}”, contentReally);
try {
getRouteDefinitions(contentReally).forEach(routeDefinition -> {
log.info(“动态路由配置: {}”, routeDefinition);
writer.delete(Mono.just(routeDefinition.getId()));
writer.save(Mono.just(routeDefinition)).subscribe();
publisher.publishEvent(new RefreshRoutesEvent(this));
});
} catch (Exception e) {
log.error(“更新动态路由配置异常: “, e);
}
}
/**
* 因在nacos配置路由携带 spring前缀,会导致yaml解析失败,因此需截取
* @return
*/
private String replaceContext(String content){
String contentDelete=content.replaceAll(“\r|\n”, “”).substring(0, content.indexOf(REPLACE)+1);
String contentReally=content.substring(contentDelete.length()+7, content.length());
return contentReally;
}
/**
* yaml转换
* @param content
* @return
*/
private List
return JSON.parseArray(JSON.toJSONString(
YamlHelper.getInstance().load(content)
), RouteDefinition.class);
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}
二、配置文件参数
server:
port: 8085
spring:
application:
name:gongfu
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes:
– id: apiconsumer 路由 ID(不是网关ID),保持唯一
目标服务地址 (加 lb 根据注册中心服务名匹配)
uri: lb://provider1
predicates:
路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)
– Path=/provider/**
必须加上StripPrefix=1,否则访问服务时会带上provider
filters:
– StripPrefix=1
discovery:
locator:
enabled: true 表明gateway开启服务注册和发现的功能,并且spring cloud gateway自动根据服务发现为每一个服务创建了一个router,这个router将以服务名开头的请求路径转发到对应的服务
lower-case-service-id: true 是将请求路径上的服务名配置为小写(因为服务注册的时候,向注册中心注册时将服务名转成大写的了
三、启动类
启动类增加@EnableDiscoverClient
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class GongfuApplication {
public static void main(String[] args) {
SpringApplication.run(GongfuApplication.class, args);
}
}
四、前后端分离解决跨域问题
(1)利用nginx反向代理,解决跨域问题
所有的请求都通过nginx,让 nginx 来区别请求是发送到前端还是网关。发送到网关的请求,让网关转发到相应的微服务。
(2)添加响应头
因为所有的请求都会经过 gateway 网关,在请求响应的过程中,经 gateway 网关给请求添加响应头,解决跨域问题。
@Configuration
public class GongfuCorsConfiguration {
@Bean
public CorsWebFilter corsWebFilter() {
UrlBasedCorsConfigurationSource ubcs = new UrlBasedCorsConfigurationSource();
// 对于任意路径(/**)都要配置跨域
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 配置跨域
corsConfiguration.addAllowedHeader(“*”); // Access-Control-Expose-Headers
corsConfiguration.addAllowedMethod(“*”); // Access-Control-Allow-Methods
corsConfiguration.addAllowedOriginPattern(“*”); // Access-Control-Allow-origin
corsConfiguration.setAllowCredentials(true); // Access-Control-Allow-Credentials
ubcs.registerCorsConfiguration(“/**”, corsConfiguration);
return new CorsWebFilter(ubcs);
}
}
这样就解决了Gateway+Nacos前后端分离中的问题了。
声明:本文部分素材转载自互联网,如有侵权立即删除 。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
丞旭猿论坛
暂无评论内容