-
disable
auto scalingand set number ofreplicasmanually -
view events in GCP to get a better idea of why application is getting killed and restarted

-
note how long it takes for app to start successfully in your current environment
- adjust number of tries for
livenessandreadinessprobes to accommodate slower start ups - enable debug logging by org.springframework.boot.availability.ApplicationAvailabilityBean
- adjust number of tries for
-
use GCP metrics to monitor application CPU and RAM usage
There is some confusion online about whether health indicators contribute to the liveness / readiness probe status. Research below confirms that liveness / readiness probe status does not depend on the health indicators as long as these conditions (causing the health indicators failure) do not prevent application from starting.
https://spring.io/blog/2020/03/25/liveness-and-readiness-probes-with-spring-boot
You should carefully consider tying external state to Liveness or Readiness and this is why Spring Boot is not adding any by default. Each application and deployment is different, but we’re committed to providing guidance and adapt defaults with the help of the community - check out the "Checking external state with Kubernetes Probes" section in our reference documentation.
Looking in the code, the usages of LivenessState.CORRECT are listed below:
- EventPublishingRunListener.started(ConfigurableApplicationContext, Duration) (org.springframework.boot.context.event)
- SpringApplicationRu
| import lombok.extern.slf4j.Slf4j; | |
| import org.aspectj.lang.ProceedingJoinPoint; | |
| import org.aspectj.lang.annotation.Around; | |
| import org.aspectj.lang.annotation.Aspect; | |
| import org.aspectj.lang.annotation.Pointcut; | |
| import org.springframework.stereotype.Component; | |
| @Aspect | |
| @Component | |
| @Slf4j |
- Dependabot does not honor Gradle's
resolutionStrategy. Here is the issue for dependabot not working with gradle's resolutionStrategy. A typical usage of Gradle's resolutionStrategy is for upgrading vulnerable dependencies that are transitive to the application. - Dependabot does not show which vulnerabilities have been resolved by the PR before PR is merged to main branch
- Dependabot uses public runners and cannot access private artifact repositories (possible workaround using private runners)
- Gradle plugin org.owasp.dependencycheck takes into account proper versions from
resolutionStrategyand also lists at least one other vulnerability that is not listed by Dependabot.
With groovyx.net.http.HTTPBuilder outdated and not ported to latest Groovy version, here is the simple code to do a REST call
String json = new URL(url).getText(
requestProperties: ['Authorization': 'Bearer ' + token]
)
JsonSlurper jsonSlurper = new JsonSlurper()
Map content = jsonSlurper.parseText(json)Better yet, newer java.net.http.HttpClient that comes w/ JRE can now be used:
| def "fetch file info"() { | |
| given: | |
| UUID fileId = UUID.randomUUID() | |
| FileMetadata response = new FileMetadata(fileId, "/somePath", "someFileName.xls", 100) | |
| wireMockServer.stubFor( | |
| get(urlPathTemplate(uri)) | |
| .withPathParam("fileId", equalTo(fileId.toString())) | |
| .withHeader(AUTHORIZATION_HEADER, expectedAuthorization) |
| import com.google.api.client.http.HttpHeaders | |
| import com.google.api.client.http.HttpResponseException | |
| import com.google.cloud.storage.StorageException | |
| import org.spockframework.spring.SpringBean | |
| import org.springframework.test.web.servlet.ResultActions | |
| import static org.hamcrest.Matchers.is | |
| import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get | |
| import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print | |
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content |
Things I don't like about java records
- record is final so it
- can't be used in inheritance
- can't be mocked in unit tests
- doesn't support builder pattern and as the number of fields grows Lombok's
@Builderbecomes preferable- although it seems to be possible to use Lombok's
@Builderwith java record
- although it seems to be possible to use Lombok's
- Getter / setter name name() vs getName()
I don't see any major advantages with using record other than its immutable nature.
- If there are commits that logically address separate issues it's easier to understand such changes as individual commits in the history rather than squashed result
- Ability to check if the commits from other branches have been merged to main (
using git branch -r --no-merge) which is especially useful for release/* deployment strategies - If a file was first renamed and then modified in more than one commit (recommended approach for git to retain history), if these commits are merged then the history is retained. Otherwise, if squashed, git might consider the rename and update as old file deletion and new file addition (depending of the percentage of the changes).
However, there is definitely a case for squashing PRs when individual commits do not provide extra value and just create more "noise".