java中的springboot使用geteway网关

网关介绍:

通俗点讲,如果我们有三个项目a(端口为8801),b(8802),c(8803)都要给外网访问那么我们势必要暴露这三个接口,项目一多暴露的端口就会多,个人认为会有一部分的安全问题。

还有,如果我们已经有了一个域名(备案完全),外网访问这三个项目,那么就需要通过域名解析出三个可用的子域名,我们需要登录到阿里云或者腾讯云的域名控制台去解析,解析完成后,如果我们使用的是宝塔面板,我们或许还需要给这三个域名去申请证书,免费的证书有效期是3个月左右,域名(项目)很多的情况下,一般不会自动续签证书,需要我们手动去续签,我们每天都要去面板上看哪个临近过期然后续签,这样很麻烦。

我们如果有了网关,这样放开端口就只需要放开这个网关项目的端口,有域名的去情况下,我们只需要解析一个子域名即可

话不多说,直接上代码:

父级项目(domain):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mj</groupId>
    <artifactId>domain</artifactId>
    <version>1.0</version>
    <packaging>pom</packaging>
    <modules>
        <module>../center</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.5.RELEASE</version>
    </parent>

    <!--夫项目 管理依赖版本-->
    <dependencyManagement>
        <dependencies>
            <!--cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR9</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--cloud Alibaba-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.8.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>
                        <!--这里配置添加自己项目启动类的全限定名-->
                        <!--                        com.mj.CenterStarter-->
                    </mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

主项目(geteway):

pom.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.mj</groupId>
        <artifactId>domain</artifactId>
        <version>1.0</version>
        <relativePath>../domain/pom.xml</relativePath>
    </parent>

    <groupId>com.mj</groupId>
    <artifactId>center</artifactId>
    <version>1.0</version>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
<!--        <dependency>-->
<!--            <groupId>com.alibaba.cloud</groupId>-->
<!--            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>-->
<!--            <version>2.2.2.RELEASE</version>-->
<!--            <exclusions>-->
<!--                <exclusion>-->
<!--                    <groupId>com.alibaba.nacos</groupId>-->
<!--                    <artifactId>nacos-client</artifactId>-->
<!--                </exclusion>-->
<!--            </exclusions>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>com.alibaba.nacos</groupId>-->
<!--            <artifactId>nacos-client</artifactId>-->
<!--            <version>1.4.1</version>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.24</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!--使用热部署出现中文乱码解决方案-->
                <configuration>
                    <fork>true</fork>
                    <!--增加jvm参数-->
                    <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
                    <!--指定入口类-->
                    <mainClass>com.mj.CenterStater</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

application.yml文件:

server:
  port: 1225
spring:
  application:
    name: center-juyou
  cloud:
    gateway:
      routes:

        - id: mysql # 路由标示,必须唯一
          uri: http://127.0.0.1:8281 # 路由的目标地址
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/mysql/** # 路径断言,判断路径是否以/mysql开头,如果是则符合,跳转路由 
            
          filters:
           - StripPrefix=1   # 去掉一层路径
# 如http://127.0.0.1:1225/msyql/controller 就会跳转至 http://127.0.0.1:8281/controller
        - id: main
          uri: http://127.0.0.1:7895
          predicates:
            - Path=/main/**
          filters:
            - StripPrefix=1

config文件夹中的两个配置文件:

package com.mj.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.DefaultCorsProcessor;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.pattern.PathPatternParser;

@Configuration
public class CorsConfigurations {
	@Bean
	public CorsResponseHeaderFilter corsResponseHeaderFilter() {
		return new CorsResponseHeaderFilter();
	}
	
	@Bean
	public CorsWebFilter corsFilter() {
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
		source.registerCorsConfiguration("/**", buildCorsConfiguration());
		
		CorsWebFilter corsWebFilter = new CorsWebFilter(source, new DefaultCorsProcessor() {
			@Override
			protected boolean handleInternal(ServerWebExchange exchange, CorsConfiguration config, 
				boolean preFlightRequest) 
			{
				// 预留扩展点
				// if (exchange.getRequest().getMethod() == HttpMethod.OPTIONS) {
					return super.handleInternal(exchange, config, preFlightRequest);
				// }

				// return true;
			}
		});
		
		return corsWebFilter;
	}
	
	private CorsConfiguration buildCorsConfiguration() {
		CorsConfiguration corsConfiguration = new CorsConfiguration();
		corsConfiguration.addAllowedOrigin("*");
		
//		corsConfiguration.addAllowedMethod(HttpMethod.OPTIONS);
//		corsConfiguration.addAllowedMethod(HttpMethod.POST);
//		corsConfiguration.addAllowedMethod(HttpMethod.GET);
//		corsConfiguration.addAllowedMethod(HttpMethod.PUT);
//		corsConfiguration.addAllowedMethod(HttpMethod.DELETE);
//		corsConfiguration.addAllowedMethod(HttpMethod.PATCH);
		//允许所有的请求方式
		 corsConfiguration.addAllowedMethod("*");
		
//		corsConfiguration.addAllowedHeader("origin");
//		corsConfiguration.addAllowedHeader("content-type");
//		corsConfiguration.addAllowedHeader("accept");
//		corsConfiguration.addAllowedHeader("x-requested-with");
//		corsConfiguration.addAllowedHeader("Referer");
//		corsConfiguration.addAllowedHeader(RequestHeaderKeys.USER_AGENT);
//		corsConfiguration.addAllowedHeader(RequestHeaderKeys.TOKEN);
//		corsConfiguration.addAllowedHeader(RequestHeaderKeys.REFRESH_TOKEN);
//		corsConfiguration.addAllowedHeader(RequestHeaderKeys.OS);
//		corsConfiguration.addAllowedHeader(RequestHeaderKeys.X_APP_KEY);
//		corsConfiguration.addAllowedHeader(RequestHeaderKeys.X_DEVICE_ID);
//		corsConfiguration.addAllowedHeader(RequestHeaderKeys.X_TOKEN);
//		允许所有的请求头
		 corsConfiguration.addAllowedHeader("*");
		
		corsConfiguration.setMaxAge(7200L);
		corsConfiguration.setAllowCredentials(true);
		return corsConfiguration;
	}
}

package com.mj.config;

import java.util.ArrayList;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.web.server.ServerWebExchange;

import reactor.core.publisher.Mono;

public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
	@Override
	public int getOrder() {
		// 指定此过滤器位于NettyWriteResponseFilter之后
		// 即待处理完响应体后接着处理响应头
		return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;
	}

	@Override
	@SuppressWarnings("serial")
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		return chain.filter(exchange).then(Mono.defer(() -> {
			exchange.getResponse().getHeaders().entrySet().stream()
					.filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
					.filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN) 
							|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)))
					.forEach(kv -> 
			{
				kv.setValue(new ArrayList<String>() {{add(kv.getValue().get(0));}});
			});
			
			return chain.filter(exchange);
		}));
	}
}

filter文件夹中的一个文件:

package com.mj.filter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;


@Component
@Order(0) //数字越小 优先级越高
@CrossOrigin()
public class AuthorizeFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange ex, GatewayFilterChain chain) {
        ServerHttpRequest request = ex.getRequest();
        String path = request.getURI().getPath();

        InetSocketAddress remoteAddress =
                request.getRemoteAddress();
        InetAddress address = remoteAddress.getAddress();
        String hostAddress = address.getHostAddress();


        // 获取当前时间
        LocalDateTime currentDateTime = LocalDateTime.now();
        // 定义日期时间格式s
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 格式化当前时间
        String formattedDateTime = currentDateTime.format(formatter);

        System.out.println("log:["+formattedDateTime+"]\t访问路径:"+path+"\t客户端ip+"+hostAddress);

        //以某某某结尾
//        if (path.endsWith("login.html") ||
//                path.endsWith("register.html")||
//                path.endsWith("js")||
//                path.endsWith("css")||
//                path.endsWith("login")||
//                path.endsWith("register")||
//                path.endsWith(".map")){
//            return chain.filter(ex);
//        }
        if (true){
            return chain.filter(ex);
        }
        ex.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return ex.getResponse().setComplete();
    }
}

启动类文件:

package com.mj;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.CrossOrigin;

@SpringBootApplication
@EnableDiscoveryClient //开启服务注册与发现
@CrossOrigin //允许跨域访问
public class CenterStater {
    public static void main(String[] args) {
        SpringApplication.run(CenterStater.class);
    }
}

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
网关Gateway)是连接不同网络的设备,也可以是负责管理网络传输的服务器。负载均衡(Load Balancing)是一种网络技术,用于分布网络请求的负载,以保持网络的可用性和性能。 在网关负载均衡配置,我们通常需要考虑以下几个方面: 1. 选择合适的负载均衡算法:负载均衡算法决定了如何将网络请求分发到不同的后端服务器上。常见的负载均衡算法有轮询、最小连接数、最短响应时间等。我们需要根据实际需求选择合适的算法,以达到最佳的负载均衡效果。 2. 设定合理的权重和优先级:如果后端服务器的性能不同,我们可以通过调整权重和优先级来实现不同服务器的负载均衡。通常,性能较好的服务器会被赋予较高的权重和优先级,以便更多的请求被分发到该服务器上。 3. 监控和自动故障转移:为了保证高可用性,我们需要监控后端服务器的状态,并在服务器发生故障时进行故障转移。这可以通过定期检查服务器的可用性来实现,一旦检测到服务器不可用,网关将自动将流量重新分发到其他可用的服务器上。 4. 配置部分服务器:在某些情况下,我们可能希望某些特定的请求被分发给特定的服务器,这可以通过配置部分服务器来实现。例如,我们可以将某些特定的API请求分发给专门处理该API的服务器。 总而言之,网关负载均衡配置是一个复杂的过程,需要考虑多个因素,并结合实际需求和场景进行合理的配置。通过合适的配置,我们可以实现高可用性和性能的优化,提升网络服务的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ζั͡ޓއއއ๓一叶之秋孤王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值