Spring Tips: Spring Cloud Gateway (Redux)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi spring fans this is singapore's famous changi airport it is widely and routinely ranked as the number one most loved airport in the world after all changi has everything well almost everything it's missing a nightclub which is a pity because it really could use one i've spent way too many nights transiting through singapore and a nightclub would be nice and you know what they even have a really nice nightclub in singapore called zuk which is a great discotheque or nightclub that you know i think they could connect i think they could install a 20 kilometer travelator from the airport to the club and then back again and that would be great this airport has to have everything because it has some very discerning patrons the country of singapore is so teensy weensy dpd that every flight out of changi airport is an international flight there are no domestic flights and no domestic terminals singapore is also a major hub of commerce in southeast asia one out of 21 people there is a millionaire that's a higher rate than in the united states you've seen crazy rich asians haven't you singapore is a very international cosmopolitan and business friendly city state and its airport reflects that jet-setter economy so the airport has everything everything you could take a guided tour go into the city maybe you could just skip the guided tour plan your layover accordingly spend the night there and go to zuk did i mention duke's pretty cool you should go to zuk if you're staying in the airport they're shopping so much shopping for everything from salted eggs to hermes to everything right xiangi has you covered but none of this tells the big picture of why it's so loved right i think it helps and i think it would be more loved if it had a nightclub but it doesn't explain why it's already so revered you enter the building then you clear immigration and then that's it that's where the similarities end at this point you've gone through a mostly automatic immigration process and now you're inside the airport but you're not behind security and this is an important part here the security happens later security is one of the parts where people spend a lot of time and their time at the airport and as a result they waste a lot of time so security is one of those things where they've delayed that to the last possible minute this is in stark contrast to most airports where security takes forever just see for example chicago's ord airport atlanta's atl airport new jersey's ewr airport london heathrow these airports are nightmare to navigate if you are pressed for time when you're ready you go to your gate leaving of course just a little bit more time than you normally would inside of an airport because here you're going to have to clear security now this is okay the queue depth the number of people that are in front of you in the security lines are going to be very small because they are at most equal to the number of passengers that have to board the one or maybe on occasion two flights that are boarding from any one given gate so each gate in changi airport has its own security machinery and its own security staff and it has its own processes to manage that this is expensive for an airport because it's redundant infrastructure and yet the result is that when people pass through there when people have to get something through the airport and onward it goes by a lot quicker so the clock time the start to finish time is a lot quicker than most other airports the reason it's so much quicker than other airports is because in a traditional airport security is in a single place it's centralized and everybody in the airport must funnel through that security that means that the queue depth might be equal to you know as many people are as are about to board a flight in the next couple hours as the airport can accommodate that means that you could be in that queue for a long time this is an obvious application of the theory of constraints we're parallelizing the work parallelization requires considerably more resources but shortens the end-to-end passenger experience so in conclusion this is why microservices are awesome so um we good we're clear i mean you understand right it's the airport infrastructure centralized monolith it's all clear right we straight we good no no you're a little confused okay well what i mean by that is that microservices are small singly focused independently deployable bounded contexts there are many work cues involved in developing software microservices are like tamagotchis they require a lot of work some work cues grow with the size of the changes to a code base while others can be paralyzed and as a result can be done with just more resources but in less time coding and testing individual features can and ought to be parallelized the individual teams you have working on microservices can deploy concurrently the more the concurrency the shorter the wall time from having an idea and seeing that whole thing delivered into production this assumes that people of course are able to develop and contribute to a code base while keeping the integration surface area to a minimum the modulus project aims to help people build modular monolithic applications spring framework tries to support loose coupling between modules and a code base in as many different ways as possible there are so many to mention but one is application context event which allows you to publish asynchronous events from one component in an application context to another without them being aware of the producer or the consumer another feature that is very convenient is the really really relaxed approach to package privacy so you can have components that participate in the application context even though they're only just packaged private this means that at compile time there's no type visibility there's no exporting of types another thing that makes it really convenient for this kind of work is that it makes it very easy to write interface-driven code and then work in terms of those interfaces so you can de-reference service implementations and test implementations and so on by a common interface then comes integration invariably after all the individual features are developed and working in isolation they need to be integrated and this work depending on the nature of the work can take a little bit of time or a long time but whatever it is it's going to be serialized work it's going to be work that gets done as all the other things have wrapped up and only as all the other things have wrapped up the only cost of course is three is the redundant changi airport like infrastructure that needs to be maintained for every single micro service like i said they're kind of like tamagotchis when you're building a monolith there are things that you need to only think about once in a blue moon that end up being a more common fixture in the work that you have to do when you start moving to microservices when you build a monolith there's work that you have to do but you only have to do it once in a blue moon things like application security jwt ydc samo who knows definitely don't use a username and password if you do that spring security lead rob winch will be sad don't make robin sad things like routing and standing up a database and message queues things like virtual machines and containers and hardware things like observability routing load balancing compression rate limiting etc there are some solutions to this problem however my friend chris richardson wrote a great book called microservices patterns for manning and in that book he talks about a pattern called the service chassis a service chassis is basically spring boot right it's a framework that optimizes as with as few configuration properties as possible the process of setting up all this stuff all these things that the framework can do while containing your java code so the service chassis is going to make as trivial as possible the work of setting up authentication and setting up routing and setting up whatever right but it's still redundant right you still have to do it for each microservice and hopefully you've got some auto configuration some spring boot starters to reduce that configuration uh and to centralize it so you can just redeploy that but it's still going to be manifest and every single application that's been deployed right every single one will have at runtime all these concerns uh in the code base itself so at runtime the deployed module is larger in terms of the things that are running in memory but cognitively it costs the developer a lot less than it would otherwise especially when amortized over all the possible applications that have been deployed right if it's just one then sure figuring out all that stuff and making it work correctly is a lot of work but if you've got a recipe for it and you don't need to do anything the second time you've used it you just plug in the relevant and extremely minimal properties to get it working that's great right that's a cost win that's a gain that's a profit an api gateway is a an api gateway like spring cloud gateway is a great way to re-centralize some of these concerns api gateways work because they're minimally invasive we don't have the cost of integration that we have to worry about because it's just a few touch point properties there's no code there's no involvement in the business logic or if there is it's minimal and you can express it in terms of an interface again because we promote decoupling right so the api gateway allows us to re-centralize some of this work and thus reuse some of that work across all of our services while reducing one of those serial cues that of integration and integration testing to as small as possible this is the best of both worlds here we get common cross-cutting kinds of concerns expressed in a single place so we get our dry principle do not repeat yourself principle i just repeat it myself and then we get individual micro services where the business logic which is subject to change because different teams are working on it can be deployed and evolved independent of other microservices so you get the best of both worlds you get to have your cake and eat it too you know what an api gateway does not normally do not ever closer to sentience what is going on with this google ai in your api gateway i don't even know what that means suppose you're a developer and you want to connect your external clients to your backend array of services but you need to handle things like course headers or reject any unauthenticated requests or you want to translate one protocol from an from another this is an ideal use case for an api gateway axbay.com is a great description of an api gateway it describes it as code that sits in front of your apis and that is a single entry point for all requests going into that system it makes the point that microservices and apis need to have consistent quality and an api gateway can help ensure that high level of quality uh for things like compression for things like security rate limiting caching etc basically api gateways and the service chassis pattern help us to clear up some of the costs some of the redundancies implied by the move to distributed systems i'm sure you're all well aware of what spring boot is so this video is not going to be an introduction to springboard itself this video will be an introduction to spring cloud gateway we made the move to microservices to get smaller singly focused and independently deployable bounded contexts and to get autonomy to get velocity to get the ability to parallelize work and to see that work released as often as frequently as possible microservices give us organizational velocity but it comes at a cost there is some duplication of work and spring cloud gateway can help you eliminate those redundancies too you can have your cake and eat it too if you embrace microservices and use an api gateway and we will on this episode of spring tips all right let's get started we're going to build a brand new application that uses spring cloud gateway so we'll go of course to my second favorite place on the internet start that spring that i owe and there we're going to build a new application called basics and in this application we're going to use the spring boot support for spring cloud gateway we're going to use the spring boot actuator and we'll use the reactive web support just for posterity i might include lumbag i'm not sure if i'll have time or reason to use it but it never hurts just in case right with that i'm pretty satisfied with my selections so i'll hit generate this will give us a brand new project where i can open up in my ide alright let's open this up in my ide and here we're going to define a route locator the contract for sprinkler gateway is very clear just create a bean of type route locator and the application context and in spring will pick it up so bean route locator return and then of course to build these beans we'll need a route locator builder so route locator builder rlb rlb dot route dot build and we're gonna have to create some routes so we'll create a route spec route spec dot path and the idea here is that you create a route and each route has three components three main components and you can create by the way as many routes as you like so i can do i can chain these together and each route spec has a predicate and the predicate can be really anything right you can say you can determine whether a request is allowed to go through based on the path based on some headers that are present based on the uri based on the host and method you know the http verb or method as we call it uh a custom query parameter present or not uh or just generally you know it doesn't match a predicate or does it match the negation of that predicate right so you have a lot of different ways of writing these predicates for our purposes let's just start with something very simple like uh hello okay so this is the path when somebody makes a call to our service our gateway service running on port 99.99 we will match that request if the path is hello and we're going to send this on to the spring.io guides page okay now the problem is that each request that comes in is preserved and forwarded or proxied to the downtrend service well of course in this case the downstream services spring that i o and there is no uri spring.io for hello so we need to change this and this is where the power of filters come in right here we can create a filter to change the outgoing request for example to change it to guides so let's go ahead and restart this now and see what we get all right so there's my brand new application let's go ahead and open this up in our browser so localhost 8080. sorry 99.99 localhost 99.99 forward slash hello and when we do that you can see very clearly that we've gotten uh you know the output from the guides page building a restful web service the styles are not working i presume there's some sort of relative path that no longer works correctly because we're no longer on that hosting port but you can see it very clearly proxy the html markup from that downstream service right and i'm able to get it from here you will see an occasion on my console that i have these exceptions related to uh this the way that nitty works on my machine this doesn't actually seem to cause any issues so you can feel free to ignore that and by the way you can give your routes an id right so you can say uh i'm gonna have this be my twitter route and then you can configure the route spec like i did before so here route spec and the path here is going to be twitter so anytime somebody sends us twitter forward slash at sign and then a twitter handle we're going to preserve that and we want to rewrite it i actually want to keep that path but rather than just changing it to something brand new i want to apply a regular expression to extract out certain fragments of the path and then forward that onward so we're going to use a filter a filter spec and here we'll say rewrite path twitter at and we're going to use a variable basically we're going to create a variable handle and when we pres when we perceive that particular predicate we want to send the request onward and we're going to do that with a rewrite so this is a very common thing you've done this no doubt in something like uh nginx or apache mod rewrite or something like that okay so there's our new path and our new our new spec so path filters and then of course the downstream uri will be twitter.com all right so there's the read write so we're taking the incoming request we're extracting out the handle and we're replacing it with just forward slash so it'll be twitter.com forward slash and actually you know what we can get rid of that get rid of that and save the user some pain so it'll go to it'll go to that uri so let's go ahead and try this out all right so hello is working now what about our twitter endpoint our twitter endpoint relies on having a path called twitter starbucks man and there you go there's the output from twitter itself proxied through to the browser uh in the in the page there and actually you can see it's the twitter markup itself has a redirect and it determines if the host is actually anything besides itself and it redirects to itself so i proxied that page loaded in the browser and i got redirected to twitter now suppose i tried doing that from my proxy from the command line where i don't have follow redirects enabled and i do local host 99.99 forward slash twitter forward slash starbucks man minus v and you see what happened there originally i got it moved permanently and it said i should go to https twitter.com starbucksman and that's what happened here it redirected me to this all right so spring cloud gateway as you can see just to demystify it is just a gateway it's just a proxy and you can act on incoming requests through filters so you have predicates and the predicates can be multi-faceted you could have the path and the host for example you could say if anything went to you know if the host header is asterisk that's spring rail and the path is hello and uh you know it's after you know zone date time now so any request that comes into the uh the service after the current when the application starts up then that'll get you know honored for example or you could say if i wanted to provide a custom predicate i could do that as well i could say new i could say async predicate new async predicate and here i'm given a chance to provide a test that's deferred it's a reactive uh non-blocking test so i can say okay well serverwebexchange.getattribute you know foo right and and so you can say return mono dot to adjust in this case the the uh non-blocking return value didn't really buy as much but you can kind of see the opportunity there anything that returns a mono of boolean for example you could have just called that to determine what this request should be allowed to go through for example so there's our very very simple filter okay so we've got a couple of we got three different things going on they were saying you know if that predicate is there if the path is there if the host is there etc now obviously i don't have any attribute named foo so let's just drop that for now but really these predicates are as flexible as you want them to be you can customize it based on all sorts of different things there you can negate etc now if we run this we'll see what happens let's see what happens when we try and run this and we don't have the host header in place curl http localhost 99.99 forward slash and then the end point there is hello okay minus v you can see it says 404 not found but minus h host test dot spring.io and there's the json and the output in the markup you can see it proxy the request because it perceived that host headers in the body one of the interesting opportunities here is that spring cloud gateway works very nicely with all the observability tools that are in spring boot itself it also provides actuator endpoints so you can see two different endpoints that are provided out of the box local host 99.99 actuator you scroll down and you can see that there's a gateway endpoint here and this gateway endpoint provides a routes sub endpoint telling us what predicates are available and so on it also provides us a matrix integration and by metrics i mean it integrates with micrometer micrometer is the metrics collection abstraction uh that we use inside of spring boot to simplify the work of collecting different kinds of statistics things like things like how much cpu we have how many requests per second we can make etc we can also use micrometer to publish our metrics to another time series database something like grafana or netflix d netflix's uh atlas or prometheus or whatever you don't have to do anything except for have actuator in the class path and opt into the metric spring cloud so here it says spring cloud gateway metrics enabled equals true so with those in place we can visit twitter starbucks man and localhost metrics and you can see that there's a key there called spring cloud gateway requests take that here and you can see a breakdown of how many requests there have been in this case one that the time the total taken uh by the whole of the processing the route uri the route id the http method the outcome was a redirect the status code that we got was moved permanently the status code that we got was 301 all of this is visible inside of these metrics that you get for free out of the box just by using spring color gateway now that we know what the basics of using spring cloud gateway look like let's stand up a service that we can then use in further demonstration of some of the more advanced features of spring cloud gateway we're going to go back to start that spring io and we're going to build a new application called customers and this is not going to be a gateway application it's just going to be a reactive web application it will eventually participate in service registration and discovery so we use the eureka discovery client support all right there's the application let's go ahead and just spin this up uaocustomers.zip there's our brand new application we can go ahead and make some changes and this is just a simple example so that we have something with which to work in the balance of our demos we're going to go ahead and pin this to a different service port so let's say 81.81 we're going to give this a name to identify it to any service registry that we use so we'll give this one the name customers let's create some sample data type customer and it's just a detail so we're going to use lumbar to create some getters and setters and some to string and some equals and hash code all that good stuff one will be an http service and event stream based endpoint and the other one will be a websocket endpoint in order for this to work we're going to need a reactive stream that produces updates to the values that we can then see trickle out in the websocket endpoint and in the service and event stream so we'll go ahead and do that here we'll create that bean that reactive publisher that emits these values here the job of this supplier is to return a new customer when asked so i'm going to assume that we've got a you know obviously i don't want to generate infinite data so i'll just have a hard-coded list of names here and we'll cycle through those names infinitely all right there's our names and we're going to cycle through that by creating a counter so private final atomic integer counter it's a new atomic integer so the goal of that code is to read through the array uh and and every single read we increment the counter and then we're just reading through the array and getting the modulus so so the goal of that is to read every single value in the array and then just constantly keep updating it but of course we don't want to have you know if we keep incrementing the number it'll keep producing numbers that will eventually exceed the bounds of the array so we're just modulusing the the count so that way we get a number that is always at most equal to either 0 or any number underneath the length of the array our now we have a customer's publisher now we have a publisher but what i want to do is i want to make it so that this publisher is delayed so that the results that we get are themselves delayed i'm going to use duration of seconds and i'll plug in let's say three seconds so each element will take three seconds to arrive let's create a reactive stream at bean publisher of type customer customers return this dot customers that way if we have two different endpoints serving the same stream of data they'll get the same number so by the you know let's say that the stream has been running for a minute and it's up to number whatever i want to make sure that when i access that data from the web sockets or from the service and event stream that i get the same new numbers right every number should be the same it shouldn't restart the stream just because i've made another request i want to get the same view of the data so i'm going to publish it and auto connect it and now i've got a reactive stream and i can then use that to create an http endpoint and a websocket endpoint so let's go ahead and create the let's go ahead and create the websocket endpoint so web socket configuration and we'll create a bean and the websocket handlers where the business logic will live and so we need to tell spring webflex to look for so let's create a new endpoint that has the websocket logic so websocket handler websocket handler return new websocket handler and our job will be to take the data that comes from the publisher reactive stream the customer reactive stream and turn it into a response so we'll say customerflux.map i'm going to take each customer private string from customer and we're going to use jacks on and in order to use jackson we need to hold our nose a little bit and deal with the try catch exceptions that get thrown for everything and deal with the try catch exceptions that get thrown everywhere so we'll say return this.objectmapper.rightvalue is stringcustomer and we'll use lumbok to swallow that exception and return this here return map c customer from customer okay now let's take each string that gets created for us and turn it into a websocket message and let's take that whole thing and send it back and send that back session dot send map all right that's the websocket handler now of course in order for this to work we need a simple url handler mapping which is the bean that will expose our website endpoint to the world make it available basically routed map.of ws customers wsh we're going to inject our websocket handler and we're going to make sure that this has higher priority in the routing for our local application okay so that's our website at logic we also need uh we also need an http endpoint so let's do that here we're going to create a rest controller class customer rest controller and you know looking back maybe i should name this customer websocket configuration and we'll create an endpoint here and this endpoint will be produces it'll produce a service and event stream and the path will be customers publisher of customer get return this dot and then all we're going to do is we're going to inject that same stream so private final publisher of customer okay there's our updated endpoint so we can try it out right now you can see it's failing because it hasn't found a service registry in which to register we'll tend to that in just a minute localhost forward slash 8080 forward slash notes so localhost localhost 8081 forward slash customers and so on so this will just keep going it'll keep going until it wraps around in the wall at this point hopefully you've got a sense of not just the core of spring color gateway but of its potential right you've got a sense of the lay of the land some of the extension points etc and we're going to deep dive into those particular extension points and some of those more advanced features in the balance of our tutorial but i figured in this situation since we've got a sort of broad understanding of what's happening now is a good time to then revisit why we have this technology why we have sprinkled gateway why it's part of the spring cloud portfolio and i asked my buddy the one the only amazing spring cloud co-founder and spring cloud gateway creator spencer gibb to answer a few questions for me it's at a conference in in boulder colorado called defrag and had listened to speakers like brendan burns and i was just there as an attendee uh netflix had blogged about zuul 2 and lots of people were anxious because it you know zul1 didn't do things like long-lived connections and and its api was fairly poor and there were lots of statics and it was it was difficult to integrate with and as i was thinking about it looking at the code watching the the development alongside of web flux you know the thought crossed in my mind that we could probably provide a better developer experience along with with better features if we did it on our own so you know rather than having to adapt things like http headers and all that stuff uh we get that kind of stuff for free with with spring webflux so i uh went ahead and built a proof of concept you know with webflux to make sure that i wasn't crazy and could actually make requests um i even switched i think i started using web client but it wasn't fully featured enough so i i went to use nettie's http client that kind of thing built a proof of concept just decided you know maybe i'm going to show this to a few folks then wrote up a google doc and sent it to dave siren brian dusseau and they were like yeah let's do this and uh it turns out it was it was a great idea because they had to rewrite zul2 and it took more than a year for them to finally open source it and and i got all this great infrastructure from the spring team from project reactor right which is so much simpler to work with than rx java and all the way to webflux right and all the primitives that live there and gateway becomes predicates and filters over webflux basically and and bridging those connections and and being able to route based on anything in the request whether that's host name or request parameters or headers not just path and that filters can be easily written on your own right they can just be a few lines and provide a much better developer experience for for folks that want to customize their gateway sure one of the the top use cases is centralized security when when we talk to customers that's that's one of their top use cases things like automated canary rollouts or another use case [Music] you can embed gateway in your applications and be able to overcome things like cross-origin requests since you can forward you know to services behind your your you know single page app or whatever you're doing um edge kind of services right you know just general proxying and load balancing and uh automatic you know kind of self configuring gateway when you plug into discovery services or something like config server or something like that where you can just refresh routes and you know change configuration and get new you know respond to challenges or new customers or new something fairly quickly with that in the last section we briefly alluded to the possibility of using service registration and discovery with spring cloud gateway we added the spring cloud starter eureka discovery client to the class path intending to be able to talk to it at some point down the line in this section we're going to look at how to do that we're going to stand up a eureka service registry now keep in mind while i'm using netflix's eureka which is a a very very popular very easy to set up for a demo choice it's not the only choice there are other implementations of the spring cloud discovery client abstraction supporting among other things apache zookeeper hashicorp console kubernetes you know labels and selectors based dns and of course cloud foundry and so while these are just the beginning you can easily plug in others with that same abstraction if you like as well we're going to create our own eureka service registry by going to start that spring rayo and here we'll build a new application called registry and we're going to add the eureka discovery server dependency and hit generate and then open this up in the ide so our application itself will be a eureka server and the application will listen on port 8761 will tell it not to register itself with itself we'll tell it not to um fetch the registry from itself and we'll give it a name not that we need to but it's just you know it's just good habit so we'll call this registry and that's it let's go ahead and start this application up now we're going to need we're going to need to talk to it from our customers application so i'm going to go ahead and restart the customers application when we started it last time it failed because it couldn't find the service registry so there's our customers service it's restarted let's go ahead and restart the customer service when we started it last time it failed because it couldn't find the service registry so the application's up and running let's go to our browser and confirm as much by going to localhost 8761 there's our service registry the eureka console is all spun up and ready for us to use and there's our single service with one instance at this hosting port that i that id etc now we can actually use this in our spring cloud gateway code i've got the spring cloud gateway code that we created earlier here in a new project i've just copied the old code i've just renamed the project to discovery and we're going to go ahead and get rid of the spring cloud gateway code from last time and keep in mind the spring cloud gateway code doesn't have any awareness of the service registry just yet so we need to add the spring cloud starter discovery client to the build just like we did for the customers build so we'll go to the prom.xml and we're going to copy and paste the eureka discovery client maven reimport and so now we've got our spring cloud gateway application we can do some interesting things without writing a line of java code first things first we can go here and we can do the locator we can set up the spring cloud discovery locator we're going to enable that now that'll mean that that means that every single service that we've added to the service registry we'll have a route automatically in our gateway code and in this case it'll create it exactly as it appears here the problem is that right now it's uppercase uppercase customers so there's actually a very convenient thing you can specify here to lowercase it so let's go ahead and restart this we'll go to localhost 99.99 and we can go to customers forward slash customers and there's the data so i'm going to the edge service i'm going to the gateway code and the gateway code is forwarding the request to any service in the service registry called customers and any path that we send after that service id is being sent you know unchanged to the downstream service all right so there we go there's our service registration and discovery integration out of the box uh we could we might be done there you might just want to do that and and be done with it you could send that you could stand that service up and deploy it as your edge service and make it so that your clients could then talk to that via the http apis and you might be done however we can go further let's create a gateway route that talks to the downstream service we'll use the route locator builder as always so gateway route locator builder rlb we'll say rlb dot route dot route dot build route spec rod spec and the path here will just be customers and the uri will be a load balanced url so load balanced to customers right so lb is a custom schema and a scheme prefix that you can use that will tell spring cloud to interpret this host path this host segment of the uri as the service id and the service registry so that might be enough right you can just take the path and then forward it on to customers unchanged in this case it would be it would get sent to customers for such customers and that might be exactly what you want okay so if we go now to uh 99.99 forward side customers we get back the data being sent from the downstream service directly so this is very convenient this ability to do load balancing is very powerful behind the scenes what's happening is it's using the spring cloud load balancer abstraction to in client memory decide which instance it should route the request to you can plug in the abstraction or the algorithm that it does for that it uses for client-side load balancing by default it's going to do at least recently used but you could also do you know round robin you could do all sorts of things the other nice benefit of this is you don't have to set up dns for the downstream service right as long as it's got a logical name which is customers it'll be in the service registry and the service registry will map to an instance of that service even if you only have one instance this is very convenient because you don't have to have magic strings around host names and the like in your source code right in your java code you can just use the logical name and whatever host import that service is found on will be resolved this way let's go ahead and shut down the customer service spring cloud gateway is aware of the service topology changes and you can listen for an event related to that by creating an application listener refresh routes event routes refreshed and here we're going to listen for the event and the event is the refresh routes event so we can interrogate that rre.getsource is an object but we can cast that to a caching route locator like this and that object has all the data a publisher of routes and we can then visit all that data we can say we want to subscribe to that route and once subscribed we can print out the results the updates one thing that's kind of interesting here is that the discovery client discovered itself in the registry so at some point our host import our service the gateway service itself registered itself in the registry as unknown you can change this application name by using spring that application name and then eventually the heartbeat eventually detected that there was that new entry in the service registry it pulled down the remote table of results and now we can see there's three entries that are being printed out periodically by the heartbeat detection uh here in my refresh routes result event listener so it discovered that entry there the same goes in the opposite direction if you were to disconnect something it would also understand that eventually this is very convenient because now we've got a very dynamic sort of fluid way of building services in this section we're going to talk about how spring cloud gateway interacts with configuration the first thing you need to understand is that spring cloud gateway is just as always with all things spring just objects right and so we've been using this dsl the route locator builder to build our route locators but that said the contract for our route locator is really trivial have you seen the interface it's just an interface with one method and it returns a publisher of routes each route in turn it's just a bunch of objects most of which are strings and integers and primitives that you could easily come up with on your own what may not be so obvious are some of these async predicate implementations but of course there are implementations that we can use out of the box and the gateway filter implementations and again there are implementations that we can use out of the box the implication being that you can construct these routes any way you like you can manually construct these routes if you like so let's look at that and we're going to keep the routes refreshment from the last time but let's go ahead and manually create a route locator so we'll do that here we're going to create a bean tab route locator i'm going to call it gateway just this last time and this time rather than using the right locator builder we'll just write the code ourselves it's not that big a deal and it'll help hopefully give us some sense of what needs to be done so we're going to create a single route we'll say route dot async we're going to give it an id so test route and then we're going to give it a async predicate and here the predicate could be you know anything let's suppose that uh we want to decide uh you know that we want to send a request to the downstream customer service and we want to accept it if it says customers but nothing else right so var uri equals exchange dot request dot uri and the path of course is the uri.path and the match is does the path contain customers if it matches then we we keep it right so return mono.just match and so this will match whether we ask for the service and event stream or the websocket stream okay so that's the the predicate there that's easy and the next thing that we want to do is want to configure the url that we want to send this to so lb customers okay and finally we want to configure the filters and here we have to wrap the filters so we say new ordered gateway filter and they can wrap any of the filters that are provided for you out of the box and you can configure any of the ones that you want but you have to use the factories right so set path gateway filter factory okay and we say ff dot and then here we create some config so config config dot to be customers right and then so we've wrapped our filter and we've used the factory we need to provide an order that's the important bit here is the ordered gateway filter so we provide an order of one and that's it that's a very simple route but it does work and then we build it and then we just return a stream containing that one route so all right there we go there's our basics application let's run it localhost 99 customers and there we go there's the data being sent from downstream so we created a route manually right this isn't using the guild the gateway route locator builder at all it's just using the default objects underneath the hood which you could do as well and that's the important part here is that the configuration is separate from the engine right so how you configure it isn't just the java api the java dsl that i showed this has some interesting implications one of which is that you can configure entire parts of your application using just the yaml or property based configuration format so let's take a look at that let's configure the application using the property based dsl i could use the property syntax but i think for this particular application yama might actually be the better fit and i don't say that lightly you know how big a fan of vm i am but we can use application.yaml and spring cloud gateway routes and then the first route is the guides the predicate that we use includes path equals guides and we're going to say that the request will only be valid after this time and we can specify a time time zone as well okay so we have two predicates here we're saying if the path is equal to guides and if it's after this time then send it to this url right so this is a new route and it's going to be picked up automatically when we restart the application so let's go ahead and restart it now okay so now when we start up there's actually three different routes that have been registered automatically uh and this one of course goes to spring that i o four six guides so we can try it by going to four such guides here in the browser and you can see the output is as we expect now let's change this predicate to be something that's in the future right so 2024 which as of the as of the recording in early 2021 is definitely in the future so now there's a 404 it doesn't exist it doesn't matter what time i you know try unless i'm going to wait three more years this isn't going to work so that's one way that's one benefit of this approach is that you can store the configuration in the yaml file and in a yaml file now this has some very interesting implications this means that we could use spring cloud gateway is kind of like infrastructure you can configure a lot of stuff you can configure a lot of it using just yammer files that's very powerful because you probably know that you can also with spring boot store configuration outside of the binary so you can actually store this in a local file system for example you could store it in console you could store it in the spring cloud config server now the spring cloud config server is a centralized configuration registry it contains all the configuration for information for various services in the cluster they all spin up and they connect to the spring cloud config server to read the configuration it is based on git as well so you can you can have a spring cloud config server whose information is backed by a git based repository or subversion based repository it can be version controlled it's auditable so now you can see who made changes when and where and the best part is you can even have spring cloud gateway dynamically reload its configuration based on those changes so let's move this file application.yaml to a directory of configuration cd desktop make dear config cd config get init touch application dot and i'll open up this file and paste in all that in so there's the predicate there i'm going to do git add application.yaml git status git commit initial commit and now i've got a repository full of configuration let's spin up a new spring cloud config server by going to start.springrail i'm going to call this the configuration service and we'll bring in the config server lumbar and that's it actually i don't even know if we need that either let's just leave it like this so downloads uao configuration hyphen service all right so we've got our config server we just need to say enable config server and in the properties go to port on 8888 i'm going to say that we want to point it to the uri of the um the configuration so spring cloud config server.get.uri equals home desktop config and you might if you're running if you create a new git repository on github remember that the default uh branch is no longer master as it will probably be when i get init something on my local machine it's going to be main for all sorts of very good reasons right so for that you need to make sure you specify the default label as main okay but for our purposes since i initialized it using git on my local machine for the moment it still defaults to master so we'll just leave it there and restart so now microservices will connect to the spring cloud config server to read their configuration and they'll hit an end point kind of like this one and they'll get their configuration from there so you can see that the configuration has been been rewritten as a an array so it's this if you're wondering how to express those routes using property file format this is basically it right this automatically translates your yaml into a property format anyway and we have a route a single route with an id guide the predicate is as such and the second predicate is this way is specified as here and then here's the url it's the same information as before so that means that we no longer need it in the actual gateways repository so let's delete it here and we're going to enable the spring cloud config client to talk to the config server in our gateway application so i'm going to go back to this screen initializer and i'm going to get the config client dependency and i'll copy and paste that into my build and reimport now that we have the spring cloud starter config client on the class path let's go ahead and change our microservice so that we are identifying ourselves accordingly spring.cloud sorry spring.application.name equals gateway uh by default if if the microservice is named bar or foo then the spring cloud config client will connect to the config server and get food at properties and food.yaml and read that into memory and then make that available as configuration all microservices no matter what their name will see the configuration in application.properties or application.yaml so i've renamed the microservice spring application name equals gateway it's going to pull in gateway.yaml gateway.properties if they exist and application.yaml and application.properties if they exist and you may you may know that spring boot has an extensible configuration mechanism spring config import config server colon right so we can actually give it a url if we wanted to but by default it'll just use spring cloud config uri which by default is equal to localhost 88.88 so i specify that here but it's redundant because that's what the default is you can override that of course all we really need the important bit is that that's what tells the client to participate in centralized configuration if we restart the application thusly we can see that we've got this endpoint here from the config server in our class path right and available here so now if we go to four size guides localhost 99 guides there's our data again it's working just fine so now let's suppose i want to change the configuration to point to a different date i can go to the config file so let's go change the configuration to point to some other date in the far-flung future i'll hit save and then the command line i'm going to commit that change into the git repository so get commit updated date and then i'm going to trigger a refresh by using the refresh actuator endpoint so i'll say curl minus x post http and now we can see on the command line on the console it says the ride has been updated and here's the new route we didn't have to restart the java application and of course if i hit this it no longer works so you can reload the configuration you can externalize it centralize it and then reconfigure the application without having to redeploy the spring cloud gateway code in this way it's acting more and more like infrastructure you can actually write java code that responds to these refresh events as well you saw of course that you have this routes refreshed event that's that gets published whenever the the routes get changed but you can also have your gateway code reconfigure itself based on uh some arbitrary predicate uh by creating a refresh scoped bean so we're gonna create a bean that gets refreshed every single time there's an event and we're going to use some external state in this case i'll just use a boolean to tell us whether we should change the behavior of the of the route or not right but again now what you should what you should take away from this is that you can talk to a database you can reconfigure based on any kind of external stimuli you like in this case i'll just have a boolean right so private final atomic boolean websockets equals false right but maybe that would we want to change that so i'm going to make this being refresh scoped and i'll create a bean of type route locator route locator builder rlb dot route.build and we'll create routes i'm going to call this the customer's endpoint and we'll say if not this dot ws.get then return this so id rs and the predicate will of course just be for such customers and if it matches we'll then send it to customers and that'll be fine the first time but let's say that we we know that if this has already been sent configured once we want to set it so that next time around it gets set as is true it's true next time right so if it's not true right now this w set equals true and then we return this and then finally going down here we're going to create a new route that proxies and forwards to the websocket endpoint and we can do that because of course spring cloud gateway understands how to do http as well as websockets so fs.setpath ws customers right that's the path of the downstream service so so the first time it gets loaded this will evaluate right um and then the gateway that we have will work with http the second time gets loaded the boolean will be true and then this will get evaluated so we'll have a websocket endpoint the second time in order to see this in action we'll create a little static website websocket application window dot add event listener uh load const ws new websocket localhost 99.99 forward slash customers and ws.ad event listener message console.log new message that data and we want to make sure that when there is an open socket we can actually send that a request with it so say ws.send and here we've got nothing to send really so just there we go let's go ahead and restart this application this gateway code localhost ws.html so this is failing at the moment it's not working let's refresh the configuration and there's the data so in this section we looked at how to create the route locators with the java api manually we looked at how to create routes with the yaml configuration format we looked at how to externalize that configuration using the spring cloud config server and then we looked at how to use the refresh scope to dynamically reconfigure our routes based on some external predicate some external influencing factor of course this is just a simple example but the idea is that you have full control over how to consume and create these routes there's also that routes event that we looked at earlier that you can use to respond to changes in those routes as well in this section we're going to talk about how to use spring cloud gateway to introduce reliability to some of your downstream services and there are many a different thing we can look at here so we're going to limit our choices and we're going to review just a few things let's go back to our gateway code i've created i've copied and pasted the original basics module and i've gutted out most of it and we've got it right here right so the few things that i've added to the class path include the spring cloud starter circuit breaker for resilience for j the resistance for j project is a third party project that has among other things a really useful implementation of a circuit breaker i've included the spring boot starter data redis reactive support so that we have something to store uh rate limiting data into and i've got the spring boot starter security dependency and we're going to come we're going to see how all these plug in in just a second but otherwise they are as we saw them before so the first thing that we're going to look at is creating a gateway okay and the gateway as before we'll use the route locator builder and now what we're going to do is we're going to we're going to look at a few different filters here right the real power of spring cloud gateways and all these filters and you've seen some of them before and by the way did i mention that you can also use global filters you can actually define a bean that gets plugged into all routes right which is very convenient if you want to do that as well so but we're going to talk about route specific filters here so we're going to create a new route as always and this is going to be pretty simple given a request called error we want to send this down to the downstream service the customer service like so and i'm going to create a new endpoint on that customer service in just a second here called error and we want to retry that request if something should go wrong now keep in mind lots of things can go wrong but we want to make sure that if something does go wrong that we retry the request let's say it's just five times now keep in mind i've just shown you the abbreviated form of this particular filter there are a good deal many more options that we could have indulged in so for example the retry config is an option right we can actually override the config itself and there you can specify what exceptions to look at how how long we should take off uh before we try again how many times we should retry what status code do we should bear aware of what exceptions we should respond to etc but there are sensible defaults for most of this so i tend to just use the default and simplest filter which is you know how many times do i retry uh it'll by default i think it'll respond to status code 500 errors and uh and so on and any io exceptions that kind of stuff so any general kind of stuff it'll it'll do the right job but you can customize it of course so let's go ahead and now that we've got our our simple filter let's go to the customer service and add that endpoint so we're going to create a new class here just for this module reliability rest controller and we're going to create a new endpoint here where we look at an id and we're going to return a response entity so and the reason we want this idea is that we can uh for our purposes just to kind of see what's happening we can keep track of who's making the request right i'm not gonna bother with authentication or anything like that but let's just store a count of how many times a request has been made to a particular path and that path will be unique by its id right so we can see how many times id one or two or three or four has made a request so here we go error path variable will be the id there and we're you know pretty straightforwardly right we're going to create a little map here private final map of string integer or atomic integer counts of errors okay and it'll just be an in-memory database kind of thing so there's that okay so now we're going to uh we're going to need to compute an atomic integer based on each update so this dot count of errors.compute id new by function and we're going to say if null should equal atomic integer atomic integer equals new atomic integer zero right that's zero uh we want to take the atomic integer and increment it uh i guess we just want to increment yeah and then we can just return this okay so now if it's zero then then the value we should have at this point in the return value here is one right because we've incremented it if it's five then we should have six in result right uh so there's the the output now we can use that to determine what kind of response to send back if result should if the result should be less than five then return response entity dot status http status service unavailable dot build all right uh dot get otherwise turn response entity dot ok map.of message and hello or no good job you did it on try number okay and we'll just uh parametrize this a little bit id all right so pretty straightforward yeah we're creating a mock endpoint that will return errors it'll return a 500 status code every single time for the first five requests which is great because we're gonna have five retries in our filter there so let's go ahead and restart this and go back to the gateway and try it out so now assuming we have a request to here and here we should see it retried five times oh i don't think we wrote out the uh the logs did we so let's fix that here system out uh error for id on count okay there so we'll log this out that way we can kind of see what's happening behind the scenes here um success now before we can start the gateway code we need to comment out uh the the uh security because it'll get in the way just temporarily of course uh we want security security is good but uh at the moment it's gonna protect everything which is a little overbearing since we're trying to get access to a certain endpoint and i haven't configured spring security so we'll run the application and now we can go to any end point we want on the gateway and that's you know assuming of course they want to go to this one endpoint so i'm going to type in you know josh whatever okay and you can see good job josh you did it on try number five so if you go to the customers endpoint you can see that it's already very quickly gotten four other requests those failed and then finally the fifth one was successful and it all happened in a blink of an eye right so that's a retry and very very powerful in itself you know a lot of things are ephemeral in this world like you might have a service that's temporarily unavailable you might have something that's not online in which case just retrying often does it right i mean if you just ask anybody who does batch programming retries are amazing so very useful in itself and again you can further customize this i've just done five one of the very natural successive steps is to then configure uh back off time like duration in milliseconds of how long you want to wait before you retry again because if you have five retries that all kind of happen really quickly like a thundering herd all in lockstep then you you end up having a cascade where you might um you might have other services that are also hitting the same error at the same time and they're also retrying in lockstep with you you know as fast as possible and so you end up causing enough traffic that you end up downing the service which is trying to come back online so it's good to have back off the next thing that we're going to look at is a circuit breaker a circuit breaker is a way to ensure some default behavior for the application should we not for whatever reason be able to connect to the downstream service so in this case we retried and eventually it resolved itself but what if it doesn't you know what if something goes wrong and we can't fix it or what if we don't want to wait we don't want to keep retrying we just want to cut bait and run right why don't try something else so we can do that easily with the circuit breaker filter but in order to use it you need to configure the circuit breaker dependency and that's what we have this resilience for j circuit breaker and therefore so our circuit breaker will look like this we're going to have an endpoint here path forward slash customers and the url will be load balanced to customers and the filter that we're going to use is a circuit breaker and for the circuit breaker config we're going to specify a fallback url so what's going to happen is it's going to attempt to do something and if it fails we'll tell it where to go instead and the only kind of scheme that you can use the only kind of url is one that starts with forward so it has to be to another endpoint on the gateway and that's fine right so here we can just have a default endpoint and here we can have a default endpoint and that works just fine because you know it's very powerful right if something goes wrong it loops back to the gateway and the gateway gets another chance to try and uh handle the request and you can create a default gateway path if you want if you want to configure things like retries and back and all that stuff you can actually configure the underlying resilience for j circuit breaker and that'll be picked up by sprinkling gateway's use of it here so let's create another route here a default route rs rs.path forward such default so when there's a request to forces default we're going to configure a filter the filter will have just a generic filter we'll just write one just to prove that you know it's happening chain dot filter exchange and we'll try it again okay so there's our filter and the other thing of course when we create a filter we need to have a route and so that route in this case will be to spring that i o for such guides okay good so there's our basic arrangement route path filters uri so we've got um our default endpoint this is going to forward to this default endpoint which means that if there's any errors in the customer service they should be redirected to the guides page so let's confirm the happy path first let's make sure that our customer service is up it's still there okay so let's let's try it out i'm going to restart the application go to the browser localhost 99 customers that's the happy path that should be working just fine now what happens if we kill the downstream service if we shut it down goodbye go to the browser and here we expect to see guides there you go i hit the request refreshed it tried it failed and then redirected to the guides so the circuit breaker is kind of like a more advanced retry but a lot of times retry might might be all you need a circuit breaker can go one step further and give you a default fallback value a fallback endpoint the next thing that we care about is making sure that we don't overwhelm our downstream service for whatever reason maybe you've got some very expensive resource or maybe you're just trying to make sure that people can't exceed the capacity you've given them so we're going to use a rate limiter to make sure that only so many requests per second are allowed to trickle on through to the downstream service in order to see this in action just like with the retries earlier we're going to create a little endpoint to kind of observe what's happening so let's go to the customers service again and we'll add yet another reliability centric endpoint here and this time we're going to see how many requests we get per second so we'll keep a map and the map will be to the current second and long as a long map to a count so um count per second all right and we'll create another endpoint just calling it hello it doesn't have to do anything in particular we don't care about the response so much as we do the times it's been invoked so we'll say return hello world okay and here we need to calculate what time it is right now so we'll log that out and then the second is now divided by a thousand last i checked milliseconds being a thousandth of a second thousandth of a second and then we want to get the count for the current second and when i compute that relative to the map so compute second new by function and again same as before we want to say okay if atomic integer should be null then atomic integer equals new atomic integer and atomic integer dot increment and get return atomic integer okay so basic structure basic arrangement of code not a big deal and finally we can just print out the results there have been okay requests four for the second called second okay okay so let's restart this and let's go back to our gateway and here we're going to introduce the rate limiter so create a new route path will be to hello because that's after all the name of the downstream service here and i don't want to have to bother setting up the path not that it's a big deal it's just why bother if you don't have to and lb customers so assuming everything went perfectly that would be enough right i'm just taking a path forwarding it on to the downstream thing but of course we know the distributed systems world uh is never ideal so we're going to use a rate limiter and the rate limiter has its own little config and basically you have to provide a a rate limiter itself the implementation and this interface is pluggable of course but there's already a very good implementation that's provided out of the box here for redis and so the idea is that let's say i do oh i don't know let's say it's 5 and we want to burst to as much as 10. so that'll be our weight limiter and this reddest rate number uses redis behind the scenes to store an atomic number to keep a count and that means that even if we have 10 different instances of this gateway uh behind a load balancer and they're all just sort of being randomly you know round robin invoked then we're still ensuring that at most so many requests get past our proxy even if there's five instances of the proxy right because we want to make sure that the downstream service doesn't get overwhelmed uh when there's too much traffic the rate limiter will be consulting account that's being kept in the redis database independent of any one java virtual machine so you know it doesn't matter what node the request hits it'll still be forced to stay within the the bounds of the raid emitter i'm using a nonsensically low number here so that we have a hope of being able to see it in action but obviously you can and should expect a great deal more uh scalability and you know requests per second in your production code so we'll plug that in and the other thing that we need to do is we need to provide a key resolver and the reason we do this is because behind the scenes like i say it's using redis so the contract here is pretty simple right you could just say mono.just my count and what that will do is it'll it'll it'll make it so that no matter who's making the request no matter where they are in the world they all have the same rate that we care about right so in effect you've only you're now only allowing a certain number of requests in in total in absolute total uh to the downstream service but that's not usually what people want what usually what people want is to allow no more than so many requests for each user because the problem isn't our absolute scale right or at least it shouldn't be usually especially today in the cloud native world we can spin up new virtual machines to respond to to change and spin up new containers etc in kubernetes so it it's not that we're trying to stop the total aggregate number of requests right scaling out horizontally is not a problem these days what we're trying to do is to stop any one user from overrunning the system you know any bad actors most people are on the system doing the right thing just trying to click around and buy things or do whatever they do on your system but occasionally you might get somebody who's trying to deny or service your system or conduct entirely too many requests per second that would be inconsistent with a human being actually acting on the system so here we can use a key resolver that takes the current principle from the request takes the principal gets the name out of the principle and then returns that key that string name if if it exists and will return empty if it doesn't exist so this is a very convenient thing because by default spring club gateway will refuse it will refuse to allow you to to make a request uh if there's no key for you and that key of course in this case corresponds to a key in redis so we're going to set up a we can set up a key resolver now to make the redis key for the count based on the username and so now each user gets so many requests per second as opposed to the whole world gets so many requests per second this is a very useful implementation you can see it's pretty trivial to implement uh it's so so trivial in fact um you know that we figured we just make it we give it a shorthand and that's actually the principle keynum is over and that's that does exactly the same thing as what i just wrote out long form does right exchange principle flat map whatever okay that's one thing uh one option um but keep in mind that that's actually also the default so if you don't include it you'll just get that as well which maybe that's all you need but in order for it to work of course you need a principle right and this is where you need spring security this is why we brought it into the build spring security well we're going to sit there and we're going to have it sit there and uh block access to the downstream service unless they're authenticated so in order to use that we need to handle two concerns one is authentication and the other is authorization reload project i'm going to create a hard name hardcoded username and password day long in this case this is a terrible idea in production of course you should take advantage of some of the more sophisticated security mechanisms that spring has an offer including but not limited to oh i don't know oauth and by the way uh while we don't have really enough time to show it in this particular video one of the more interesting applications of spring cloud gateway is to use it as a token relay so you can have it forward authentication tokens from clients down to the downstream services and so in that way spring cloud gateway ends up being your centralized federated uh authentication mechanism okay so uh one user with the username and password hard coded in the source code terrible idea again don't do this in production and then we need authorization and that's just the question of what endpoints can you know downstream components use okay and then we have the question we have the choice we have the discussion of authorization which is really just uh a discussion of what endpoints can a client have access to once they're inside the system so http dot build but we're going to comment out some we're going to disable certain things and set up certain things so a e dot any exchange permit all we want to make sure that that one endpoint the one we're trying to put behind the rate emitter is secure so hello path matchers hello authenticated all right and finally i want to say csrf i'm going to disable that and then finally we want to enable hd basic alrighty so there's our basic uh security infrastructure this is just an absolute hello world spring security application after all nothing fancy we got a redis rate limiter and if we understand everything correctly we've got a rate limiter it says it's going to allow so many requests to the downstream service and we should be able to see those counts those requests reflect on the output of the service as we make those requests so let's go ahead and restart the gateway and we'll see what happens so so there's our endpoint hello let's invoke it so curl um minus u j long pw http localhost 99.99 forward slash hello and there's the request right so that worked we can see it in a there's been one request for this in this one second now let's try let's try drive some traffic to it so while true to done you can see it never gets above 10 right that's our burst so that's how you do a rate limiter pretty trivial huh pretty easy so now with spring cloud gateway and the reliability patterns oops you can see we're getting the errors because there's no more it's not allowing me to there's no downstream service so it's failing there and i didn't put any retry there so now with spring cloud gateway we've looked at a number of different patterns to support reliability we looked at retries we looked at rate limiting and we looked at circuit breakers this is just the beginning obviously there's so many more that we could look at but i think you've got a good sense of what's possible spring hub gateway is a phenomenal piece of open source technology that's designed to meet production use cases and scale at ease unfortunately we don't get to have a very strong opinion in our java source code about how you deploy this thing in production because we don't know what production is for you we do have two products two commercial offerings uh that might help you in two particular environments first of all we have spring cloud gateway for cloud foundry uh which you can use in a cloud foundry centric environment uh using something like the do application service and then we have the spring cloud gateway for kubernetes which we just released the spring cloud gateway offering for kubernetes is a commercial product that's designed to help you operationalize spring cloud gateway to learn more about this i wanted to talk to the amazing chris sterling who's the lead of spring cloud gateway for kubernetes i think there's some use cases that are typical across many of the gateway implementations so some of those are things like security if i want to hook into for a single sign-on into identity provider of my choice in the enterprise maybe an octa or auth0 or something like that then i can actually connect that in and have all the filters and predicates that are associated with that in the commercial products so for instance log in you should be able to automatically be redirected to login those aren't in the open source you could add them in if you want to but you'd have to create all of that for yourself with spring security and and we've kind of generalized it so it's easy to use and then the other thing is uh we've actually packaged in uh some additional filters like client certificates for mtls you kind of get a lot of things out of the box rate limiting we have session management if you do an ha configuration that's something you really got to think about if you're if you're creating your own gateway i don't want to run just one instance i probably run around more than one so that i don't have downtime that session management we actually do through an in-memory data grid and some other things you have to think about if you're deploying to a particular platform like kubernetes uh the operations aspect so day two operations what happens after you deploy the first time how do you do upgrades how do you manage uh backwards compatibility how do you do rollbacks and and how do you integrate with the platform so see the logs be able to describe events we've done all that for you so we actually have a sprint cloud gateway operator on kubernetes that go and go ahead and interact with the kate's api is able to provide all that information for you what's going on all right spring fans i hope you got something out of that video i hope you liked spring cloud gateway as much as i do obviously it's awesome right and there's a lot of really cool possibilities here uh i hope you learned something i hope you had fun along the way thank you so much for watching as always you may have noticed if you're a long time watcher of the spring tips series that things are a little different now things are getting bigger and better and so i hope you'll stay tuned and join us for the adventure obviously i am going to be here and i hope you will be too i am as always your host spring developer advocate josh long and i hope you enjoy your journey to production
Info
Channel: SpringDeveloper
Views: 90,223
Rating: undefined out of 5
Keywords: spring, spring boot, spring cloud, kubernetes, java
Id: puIJ1Mn9_LE
Channel Id: undefined
Length: 99min 9sec (5949 seconds)
Published: Tue Feb 23 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.