Skip to main content

Posts

Showing posts from October, 2025

Caching successful DNS in modern Java

Things have moved on a bit since I set up a custom DNS resolver for microservices to enable them to continue to use known successfully resolved addresses when DNS resolution subsequently fails. Since Java 22 we can specify a value in a file in the JDK to have the option of continuing to use successful lookup results even after the TTL expires.  The property name is:  networkaddress.cache.stale.ttl https://bugs.openjdk.org/browse/JDK-8306653 The compromise  A trade-off to consider when applying that approach instead of a customised DNS Resolver is that we would not have the option of detecting when normal DNS resolution has failed. Hypothetical situation Let's suppose that a minor adjustment was applied to the deployment approach for rolling out a new version of microservices within the organisation's VPC. We might start to notice intermittent errors showing in our logs, where some unintended temporary DNS clear out results in continuing to send requests to the old address...

Mitigating DNS issues with custom DNS resolver

Context  The recent AWS outage that involved DNS lookups for DynamoDB failing to resolve to any address reminded me of a situation that sometimes showed up in the error logs of some microservices that I used to maintain. I'll spare you the details of the issue - partly because I can't remember them almost a decade later. How I went about reducing the impact of a temporary blip in DNS availability is the focus of this post, as I believe that the same approach could have reduced the impact of the AWS incident (with caveats, because "it depends" is universal). A bit about microservices Most microservices only communicate with a limited range of other services to perform their functionality. For this post we could consider DynamoDB as an example of a system that our microservice needs to be able to interact with, but others might typically include: metrics service logging service some service developed for data lookup feature flagging service configuration management serv...

AWS outage - It wasn't just DNS

The AWS outage that temporarily took down so much of the Internet this week has been reported as being due to a DNS issue, but that wasn't the root cause. AWS have posted details of the incident  that explains how a race condition in the mechanism in place for updating the DNS records ultimately caused the problem. I suspect that the possibilty of the race condition occurring may have been increased by changes required for the use of IPv6 for DynamoDB, as that would have involved expanding the amount of data involved. It will be interesting to see if AWS offers up more details of their approach to eliminating the race condition. As much as anything, I'm curious to find out what is similar to the race condition that I worked through earlier this year.

How UFO protected from DynamoDB outages

Context - The October 21 2025 AWS Outage  I've just read a news article about Amazon Web Services (AWS) having a problem with their DynamoDB service which impacted a lot of their customers in the popular / vital US-EAST-1 region. This reminded me of another time that relying on DynamoDB caused an outage for one of the companies that I was working for when I lived in London, and how we went about preventing that from happening again. "It's always DNS" "B ased on our investigation, the issue appears to be related to DNS resolution of the DynamoDB API endpoint in US-EAST-1."   It's a cliché that outages on the Internet are often caused by some issue involving DNS, that happened to match up with the root cause this time around. What's the UFO? My team's core service was for capturing metadata about customers' usage of various components of the website. Because the service relied on DynamoDB for storing that information, we came up with a fallback...

Records in Java

What are they? On the surface, records seem to just be syntactic sugar for producing a class that can hold some specific combination of data. They can be used to make code less verbose, but there's more to them than that.  What do we get for free? equals, hashCode, and toString methods are automatically implemented. If we need to deviate from the default behaviour of these methods then we can still specify the implementation in the same way that we would override those methods in a normal class. What else is special? Records are implicitly final, so you cannot extend from them with a sub-class. If you want to combine them with some other data then declare another Record that contains the original as a component. That doesn't prevent us from including generics or annotations in the same way that we do with regular classes.  Why are they? Records are a special type of class in Java that enables developers to represent their data with less of an extensible mindset, that aligns wi...

Java best practices, for features introduced from Java 9 to Java 25

I've just watched a recording of a presentation by Stephen Colbourne from Devoxx Belgium " The New Java Best Practices by Stephen Colebourne ". Some of them I agreed with, some I am yet to warm to. I haven't made much use of "var" in place of specifying a variable type, so I still find code more readable when the type is specified. I am fully onboard with the best practice about the use of modules, "arguably the biggest change since Java 8". unnamed variables came in Java 22, which might explain why I haven't encountered it so far - as companies tend to stick to long term support (LTS) versions of the language so I only got to Java 21. markdown docs. Check out the Inside Java podcast about this ( https://inside.java/2025/01/21/podcast-034/ ) Optional and null - the code style example shows how Optional can flow as more readable This is not an exhaustive breakdown of what Colbourne covered, so I recommend that you take a look for yourself.

AI Wars - attack of the clones

I've been checking in some of my experimental code with GitHub repositories over the last while, and noticed that the "Traffic" section under "Insights" shows a dozen or so clones on each repo. I don't have any real followers, so I'm starting going with the assumption that the cloning will be by some automated systems picking up my code for use by artificial intelligence code assistants. Just a pity that GitHub does not offer any way of monitoring the origin of these clones. There's also a possibility that some of the traffic may relate to Dependabot, but in the interests of keeping this post with it's amusing title I'm going to check for that after posting.   (Disclaimer: This post has no connection to Star Wars, or Disney's trademark on "Attack of the Clones", and is not promoting any product or service)

Constructors - another way Java 25 can be subtly different

Constructors are still super - eventually  Java 25 has introduced a change to the way that constructors work in the inheritance hierarchy. In previous versions of Java, if we have a class that extends another class then all constructors of the subclass have to either specify a constructor from the base class as the first operation or automatically have the default zero arguments constructor applied by default - or call on alternate constructor and get the subclass's constructor invoked via that. In Java 25 it is now valid to call super() later in the constructor. So, we could have the following as valid code... public class SomeBaseClass { SomeBaseClass () { System . out .println( "Hello from SomeBaseClass constructor" ); } } public class SomeSubClass extends SomeBaseClass { SomeSubClass () { System . out .println( "Hello from SomeSubClass constructor" ); super (); } } public class ConstructorDemo { static void main ()...