This commit is contained in:
shuhongfan
2023-09-04 16:40:17 +08:00
commit cf5ac25c14
8267 changed files with 1305066 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
<?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">
<parent>
<artifactId>sentinel-demo</artifactId>
<groupId>com.alibaba.csp</groupId>
<version>1.8.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sentinel-demo-zuul2-gateway</artifactId>
<dependencies>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-zuul2-adapter</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.zuul</groupId>
<artifactId>zuul-core</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>${javax.annotation-api.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.28</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.28</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.8</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,34 @@
package com.alibaba.csp.sentinel.demo.zuul2.gateway;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import com.netflix.zuul.filters.FilterRegistry;
import com.netflix.zuul.filters.ZuulFilter;
public class FiltersRegisteringService {
private final List<ZuulFilter> filters;
private final FilterRegistry filterRegistry;
@Inject
public FiltersRegisteringService(FilterRegistry filterRegistry, Set<ZuulFilter> filters) {
this.filters = new ArrayList<>(filters);
this.filterRegistry = filterRegistry;
}
public List<ZuulFilter> getFilters() {
return filters;
}
@PostConstruct
public void initialize() {
for (ZuulFilter filter: filters) {
this.filterRegistry.put(filter.filterName(), filter);
}
}
}

View File

@@ -0,0 +1,87 @@
package com.alibaba.csp.sentinel.demo.zuul2.gateway;
import com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPathPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayParamFlowItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import java.util.HashSet;
import java.util.Set;
public class GatewayRuleConfig {
public void doInit() {
// Prepare some gateway rules and API definitions (only for demo).
// It's recommended to leverage dynamic data source or the Sentinel dashboard to push the rules.
initCustomizedApis();
initGatewayRules();
}
private void initCustomizedApis() {
Set<ApiDefinition> definitions = new HashSet<>();
ApiDefinition api1 = new ApiDefinition("some_customized_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem().setPattern("/images"));
add(new ApiPathPredicateItem().setPattern("/comments")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
ApiDefinition api2 = new ApiDefinition("another_customized_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem().setPattern("/**")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
definitions.add(api1);
definitions.add(api2);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
private void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("images")
.setCount(10)
.setIntervalSec(1)
);
rules.add(new GatewayFlowRule("images")
.setCount(2)
.setIntervalSec(2)
.setBurst(2)
.setParamItem(new GatewayParamFlowItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_CLIENT_IP)
)
);
rules.add(new GatewayFlowRule("comments")
.setCount(3)
.setIntervalSec(1)
.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)
.setMaxQueueingTimeoutMs(6000)
.setParamItem(new GatewayParamFlowItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_HEADER)
.setFieldName("X-Sentinel-Flag")
)
);
rules.add(new GatewayFlowRule("comments")
.setCount(1)
.setIntervalSec(1)
.setParamItem(new GatewayParamFlowItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
.setFieldName("pa")
)
);
rules.add(new GatewayFlowRule("some_customized_api")
.setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
.setCount(5)
.setIntervalSec(1)
.setParamItem(new GatewayParamFlowItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
.setFieldName("pn")
)
);
GatewayRuleManager.loadRules(rules);
}
}

View File

@@ -0,0 +1,61 @@
package com.alibaba.csp.sentinel.demo.zuul2.gateway;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.config.DynamicIntProperty;
import com.netflix.discovery.EurekaClient;
import com.netflix.netty.common.accesslog.AccessLogPublisher;
import com.netflix.netty.common.channel.config.ChannelConfig;
import com.netflix.netty.common.channel.config.CommonChannelConfigKeys;
import com.netflix.netty.common.metrics.EventLoopGroupMetrics;
import com.netflix.netty.common.proxyprotocol.StripUntrustedProxyHeadersHandler;
import com.netflix.netty.common.ssl.ServerSslConfig;
import com.netflix.netty.common.status.ServerStatusManager;
import com.netflix.spectator.api.Registry;
import com.netflix.zuul.FilterLoader;
import com.netflix.zuul.FilterUsageNotifier;
import com.netflix.zuul.RequestCompleteHandler;
import com.netflix.zuul.context.SessionContextDecorator;
import com.netflix.zuul.netty.server.BaseServerStartup;
import com.netflix.zuul.netty.server.DirectMemoryMonitor;
import com.netflix.zuul.netty.server.ZuulServerChannelInitializer;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.group.ChannelGroup;
@Singleton
public class SampleServerStartup extends BaseServerStartup {
@Inject
public SampleServerStartup(ServerStatusManager serverStatusManager, FilterLoader filterLoader, SessionContextDecorator sessionCtxDecorator, FilterUsageNotifier usageNotifier, RequestCompleteHandler reqCompleteHandler, Registry registry, DirectMemoryMonitor directMemoryMonitor, EventLoopGroupMetrics eventLoopGroupMetrics, EurekaClient discoveryClient, ApplicationInfoManager applicationInfoManager, AccessLogPublisher accessLogPublisher) {
super(serverStatusManager, filterLoader, sessionCtxDecorator, usageNotifier, reqCompleteHandler, registry, directMemoryMonitor, eventLoopGroupMetrics, discoveryClient, applicationInfoManager, accessLogPublisher);
}
@Override
protected Map<Integer, ChannelInitializer> choosePortsAndChannels(ChannelGroup clientChannels) {
Map<Integer, ChannelInitializer> portsToChannels = new HashMap<>();
int port = new DynamicIntProperty("zuul.server.port.main", 8085).get();
String mainPortName = "main";
ChannelConfig channelConfig = BaseServerStartup.defaultChannelConfig(mainPortName);
ServerSslConfig sslConfig;
/* These settings may need to be tweaked depending if you're running behind an ELB HTTP listener, TCP listener,
* or directly on the internet.
*/
ChannelConfig channelDependencies = defaultChannelDependencies(mainPortName);
channelConfig.set(CommonChannelConfigKeys.allowProxyHeadersWhen, StripUntrustedProxyHeadersHandler.AllowWhen.ALWAYS);
channelConfig.set(CommonChannelConfigKeys.preferProxyProtocolForClientIp, false);
channelConfig.set(CommonChannelConfigKeys.isSSlFromIntermediary, false);
channelConfig.set(CommonChannelConfigKeys.withProxyProtocol, false);
portsToChannels.put(port, new ZuulServerChannelInitializer(port, channelConfig, channelDependencies, clientChannels));
logPortConfigured(port, null);
return portsToChannels;
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.demo.zuul2.gateway;
import java.io.IOException;
import com.google.inject.Injector;
import com.google.inject.Scopes;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.appinfo.providers.MyDataCenterInstanceConfigProvider;
import com.netflix.config.ConfigurationManager;
import com.netflix.governator.InjectorBuilder;
import com.netflix.zuul.netty.server.BaseServerStartup;
import com.netflix.zuul.netty.server.Server;
/**
* <p>The Zuul 2.x demo with Sentinel gateway flow control.</p>
* <p>Run with {@code -Dcsp.sentinel.api.type=1} to mark the demo as API gateway.</p>
*
* @author wavesZh
*/
public class ZuulBootstrap {
public static void main(String[] args) {
new ZuulBootstrap().start();
}
public void start() {
Server server;
try {
// Load sample rules. You may also manage rules in Sentinel dashboard.
new GatewayRuleConfig().doInit();
ConfigurationManager.loadCascadedPropertiesFromResources("application");
Injector injector = InjectorBuilder.fromModule(new ZuulModule()).createInjector();
injector.getInstance(FiltersRegisteringService.class);
BaseServerStartup serverStartup = injector.getInstance(BaseServerStartup.class);
server = serverStartup.server();
server.start(true);
} catch (IOException e) {
e.printStackTrace();
}
}
public static class ZuulModule extends ZuulSampleModule {
@Override
protected void configure() {
//DataCenterInfo
bind(EurekaInstanceConfig.class)
.toProvider(MyDataCenterInstanceConfigProvider.class)
.in(Scopes.SINGLETON);
super.configure();
}
}
}

View File

@@ -0,0 +1,32 @@
package com.alibaba.csp.sentinel.demo.zuul2.gateway;
import com.alibaba.csp.sentinel.adapter.gateway.zuul2.filters.endpoint.SentinelZuulEndpoint;
import com.alibaba.csp.sentinel.adapter.gateway.zuul2.filters.inbound.SentinelZuulInboundFilter;
import com.alibaba.csp.sentinel.adapter.gateway.zuul2.filters.outbound.SentinelZuulOutboundFilter;
import com.alibaba.csp.sentinel.demo.zuul2.gateway.filters.Route;
import com.google.inject.AbstractModule;
import com.google.inject.multibindings.Multibinder;
import com.netflix.zuul.BasicFilterUsageNotifier;
import com.netflix.zuul.DynamicCodeCompiler;
import com.netflix.zuul.FilterFactory;
import com.netflix.zuul.FilterUsageNotifier;
import com.netflix.zuul.filters.ZuulFilter;
import com.netflix.zuul.groovy.GroovyCompiler;
import com.netflix.zuul.guice.GuiceFilterFactory;
public class ZuulClasspathFiltersModule extends AbstractModule {
@Override
protected void configure() {
bind(DynamicCodeCompiler.class).to(GroovyCompiler.class);
bind(FilterFactory.class).to(GuiceFilterFactory.class);
bind(FilterUsageNotifier.class).to(BasicFilterUsageNotifier.class);
Multibinder<ZuulFilter> filterMultibinder = Multibinder.newSetBinder(binder(), ZuulFilter.class);
filterMultibinder.addBinding().toInstance(new SentinelZuulInboundFilter(500));
filterMultibinder.addBinding().toInstance(new SentinelZuulOutboundFilter(500));
filterMultibinder.addBinding().toInstance(new SentinelZuulEndpoint());
filterMultibinder.addBinding().toInstance(new Route());
}
}

View File

@@ -0,0 +1,61 @@
package com.alibaba.csp.sentinel.demo.zuul2.gateway;
import com.google.inject.AbstractModule;
import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.netty.common.accesslog.AccessLogPublisher;
import com.netflix.netty.common.status.ServerStatusManager;
import com.netflix.spectator.api.DefaultRegistry;
import com.netflix.spectator.api.Registry;
import com.netflix.zuul.BasicRequestCompleteHandler;
import com.netflix.zuul.FilterFileManager;
import com.netflix.zuul.RequestCompleteHandler;
import com.netflix.zuul.context.SessionContextDecorator;
import com.netflix.zuul.context.ZuulSessionContextDecorator;
import com.netflix.zuul.init.ZuulFiltersModule;
import com.netflix.zuul.netty.server.BaseServerStartup;
import com.netflix.zuul.netty.server.ClientRequestReceiver;
import com.netflix.zuul.origins.BasicNettyOriginManager;
import com.netflix.zuul.origins.OriginManager;
import com.netflix.zuul.stats.BasicRequestMetricsPublisher;
import com.netflix.zuul.stats.RequestMetricsPublisher;
/**
* Zuul Sample Module
*
* Author: Arthur Gonigberg
* Date: November 20, 2017
*/
public class ZuulSampleModule extends AbstractModule {
@Override
protected void configure() {
// sample specific bindings
bind(BaseServerStartup.class).to(SampleServerStartup.class);
// use provided basic netty origin manager
bind(OriginManager.class).to(BasicNettyOriginManager.class);
// zuul filter loading
install(new ZuulFiltersModule());
bind(FilterFileManager.class).asEagerSingleton();
install(new ZuulClasspathFiltersModule());
// general server bindings
// health/discovery status
bind(ServerStatusManager.class);
// decorate new sessions when requests come in
bind(SessionContextDecorator.class).to(ZuulSessionContextDecorator.class);
// atlas metrics registry
bind(Registry.class).to(DefaultRegistry.class);
// metrics post-request completion
bind(RequestCompleteHandler.class).to(BasicRequestCompleteHandler.class);
// discovery client
bind(AbstractDiscoveryClientOptionalArgs.class).to(DiscoveryClient.DiscoveryClientOptionalArgs.class);
// timings publisher
bind(RequestMetricsPublisher.class).to(BasicRequestMetricsPublisher.class);
// access logger, including request ID generator
bind(AccessLogPublisher.class).toInstance(new AccessLogPublisher("ACCESS",
(channel, httpRequest) -> ClientRequestReceiver.getRequestFromChannel(channel).getContext().getUUID()));
}
}

View File

@@ -0,0 +1,17 @@
package com.alibaba.csp.sentinel.demo.zuul2.gateway.filters;
import com.netflix.zuul.filters.http.HttpSyncEndpoint;
import com.netflix.zuul.message.http.HttpRequestMessage;
import com.netflix.zuul.message.http.HttpResponseMessage;
import com.netflix.zuul.message.http.HttpResponseMessageImpl;
import org.apache.http.HttpStatus;
public class NotFoundEndpoint extends HttpSyncEndpoint {
@Override
public HttpResponseMessage apply(HttpRequestMessage request) {
HttpResponseMessage response = new HttpResponseMessageImpl(request.getContext(), request, HttpStatus.SC_NOT_FOUND);
response.finishBufferedBodyIfIncomplete();
return response;
}
}

View File

@@ -0,0 +1,36 @@
package com.alibaba.csp.sentinel.demo.zuul2.gateway.filters;
import com.netflix.zuul.context.SessionContext;
import com.netflix.zuul.filters.http.HttpInboundSyncFilter;
import com.netflix.zuul.message.http.HttpRequestMessage;
import com.netflix.zuul.netty.filter.ZuulEndPointRunner;
public class Route extends HttpInboundSyncFilter {
@Override
public HttpRequestMessage apply(HttpRequestMessage request) {
SessionContext context = request.getContext();
switch (request.getPath()) {
case "/images":
context.setEndpoint(ZuulEndPointRunner.PROXY_ENDPOINT_FILTER_NAME);
context.setRouteVIP("images");
break;
case "/comments":
context.setEndpoint(ZuulEndPointRunner.PROXY_ENDPOINT_FILTER_NAME);
context.setRouteVIP("comments");
break;
default:
context.setEndpoint(NotFoundEndpoint.class.getCanonicalName());
}
return request;
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter(HttpRequestMessage msg) {
return true;
}
}

View File

@@ -0,0 +1,16 @@
zuul.server.port.main=8887
# Deactivate Eureka
eureka.registration.enabled = false
eureka.preferSameZone = false
eureka.shouldUseDns = false
eureka.shouldFetchRegistry=false
# Loading Filters
zuul.filters.packages = com.netflix.zuul.filters.common,com.alibaba.csp.sentinel.adapter.gateway.zuul2.filters.endpoint,com.alibaba.csp.sentinel.demo.zuul2.gateway.filters
# Routing to proxied back-end services
comments.ribbon.listOfServers=localhost:8081
comments.ribbon.client.NIWSServerListClassName=com.netflix.loadbalancer.ConfigurationBasedServerList
images.ribbon.listOfServers=localhost:8082
images.ribbon.client.NIWSServerListClassName=com.netflix.loadbalancer.ConfigurationBasedServerList

View File

@@ -0,0 +1,6 @@
log4j.rootLogger=INFO,stdout
# stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=com.netflix.zuul.logging.FilteredPatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %-5p %c [%t] %m%n