{"id":1264,"date":"2022-02-13T20:59:42","date_gmt":"2022-02-14T03:59:42","guid":{"rendered":"https:\/\/bullyrooks.com\/?p=1264"},"modified":"2022-02-13T20:59:42","modified_gmt":"2022-02-14T03:59:42","slug":"kube-cloud-pt3-health-indicators","status":"publish","type":"post","link":"https:\/\/bullyrooks.com\/index.php\/2022\/02\/13\/kube-cloud-pt3-health-indicators\/","title":{"rendered":"Kube Cloud Pt3 | Health Indicators"},"content":{"rendered":"\n<p>Spring offers a way to tell if your services and their dependent resources are up and healthy.  Kubernetes can leverage this functionality via their liveness and readiness probes to report if pods are available to service requests.  In this session, we&#8217;re going to enable and connect those health checks.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"enable-health-endpoint-on-message-generator\">Enable Health Endpoint on <code>message-generator<\/code><\/h2>\n\n\n\n<p>Switch over to your message-generator project and start a new branch<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ git checkout -b health\r\nSwitched to a new branch 'health'\r<\/code><\/pre>\n\n\n\n<p>Update <code>pom.xml<\/code> to add the actuator dependency<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>        &lt;!-- Health Checks and Metrics -->\r\n        &lt;dependency>\r\n            &lt;groupId>org.springframework.boot&lt;\/groupId>\r\n            &lt;artifactId>spring-boot-starter-actuator&lt;\/artifactId>\r\n        &lt;\/dependency><\/code><\/pre>\n\n\n\n<p>You may need to reload your maven dependencies to make sure that this new library is being brought in correctly.<\/p>\n\n\n\n<p>Next, create an <code>application.yaml<\/code> in <code>src\/main\/resource<\/code> (remove application.properties if it exists)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>spring:\r\n  application:\r\n    name: message-generator\r\nmanagement:\r\n  endpoints:\r\n    web:\r\n      exposure:\r\n        include: \"*\"\r\n  endpoint:\r\n    health:\r\n      probes:\r\n        enabled: true\r\n      show-details: always\r\n  health:\r\n    livenessstate:\r\n      enabled: true\r\n    readinessstate:\r\n      enabled: true<\/code><\/pre>\n\n\n\n<p>Here&#8217;s what&#8217;s happening:  <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>setting our spring application name (which is just good practice)<\/li><li>enabling all actuator endpoints.  This might not be generally a safe practice as there may be some useful information here which you will probably want to secure.<\/li><li>Turn on the liveness and readiness health probes and allow the details to be shown on the health endpoint<\/li><\/ul>\n\n\n\n<p>Some really good information about liveness and readiness are <a href=\"https:\/\/www.baeldung.com\/spring-liveness-readiness-probes\">here<\/a>.  Some additional information about actuator and the various endpoints we enabled is <a href=\"https:\/\/www.baeldung.com\/spring-boot-actuators\">here<\/a>.<\/p>\n\n\n\n<p>Now start up your application and hit the health endpoint (<code>\/actuator\/health<\/code>).  You should see something like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"857\" height=\"732\" src=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-4.png?resize=857%2C732&#038;ssl=1\" alt=\"\" class=\"wp-image-1265\" srcset=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-4.png?w=857&amp;ssl=1 857w, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-4.png?resize=300%2C256&amp;ssl=1 300w, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-4.png?resize=768%2C656&amp;ssl=1 768w\" sizes=\"auto, (max-width: 857px) 100vw, 857px\" data-recalc-dims=\"1\" \/><\/figure>\n\n\n\n<p>Now let&#8217;s go back to our helm configuration and enable those liveness and readiness probe endpoints.  Modify your <code>deployment.yaml<\/code> in <code>helm\/message-generator\/templates<\/code> to reflect this<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>          livenessProbe:\r\n            httpGet:\r\n              path: \/actuator\/health\/liveness\r\n              port: 8080\r\n            initialDelaySeconds: 15\r\n          readinessProbe:\r\n            httpGet:\r\n              path: \/actuator\/health\/readiness\r\n              port: 8080\r\n            initialDelaySeconds: 15<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"commit-and-push\">Commit and Push<\/h2>\n\n\n\n<p>Now push up to build and test<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ git add .\n\n$ git commit -m \"added health checks\"\r\n&#91;health f69d658] added health checks\r\n 4 files changed, 32 insertions(+), 9 deletions(-)\r\n delete mode 100644 src\/main\/resources\/application.properties\r\n create mode 100644 src\/main\/resources\/application.yaml\n\r\n$ git push\r\nfatal: The current branch health has no upstream branch.\r\nTo push the current branch and set the remote as upstream, use\r\nCompressing objects: 100% (9\/9), done.\r\nWriting objects: 100% (11\/11), 1.00 KiB | 512.00 KiB\/s, done.\r\nTotal 11 (delta 5), reused 0 (delta 0), pack-reused 0\r\nremote: Resolving deltas: 100% (5\/5), completed with 5 local objects.\r\nremote:\r\nremote: Create a pull request for 'health' on GitHub by visiting:\r\nremote:      https:\/\/github.com\/bullyrooks\/message-generator\/pull\/new\/health\r\nremote:\r\nTo github.com-bullyrook:bullyrooks\/message-generator.git\r\n * &#91;new branch]      health -> health\r\nBranch 'health' set up to track remote branch 'health' from 'origin'.\r\n<\/code><\/pre>\n\n\n\n<p>When the build completes succesfully, merge to main<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ git checkout main\r\nSwitched to branch 'main'                    \r\nYour branch is up to date with 'origin\/main'.\n\n$ git merge health                                                \r\nUpdating 638c8dd..f69d658\r\nFast-forward\r\n helm\/message-generator\/templates\/deployment.yaml | 16 ++++++++--------\r\n pom.xml                                          |  6 ++++++\r\n src\/main\/resources\/application.properties        |  1 -\r\n src\/main\/resources\/application.yaml              | 18 ++++++++++++++++++\r\n 4 files changed, 32 insertions(+), 9 deletions(-)\r\n delete mode 100644 src\/main\/resources\/application.properties\r\n create mode 100644 src\/main\/resources\/application.yaml\r\n\n$ git push\r\nTotal 0 (delta 0), reused 0 (delta 0), pack-reused 0\r\nTo github.com-bullyrook:bullyrooks\/message-generator.git\r\n   638c8dd..f69d658  main -> main\r\n<\/code><\/pre>\n\n\n\n<p>And you should see it via postman<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"855\" height=\"741\" src=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-5.png?resize=855%2C741&#038;ssl=1\" alt=\"\" class=\"wp-image-1266\" srcset=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-5.png?w=855&amp;ssl=1 855w, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-5.png?resize=300%2C260&amp;ssl=1 300w, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-5.png?resize=768%2C666&amp;ssl=1 768w\" sizes=\"auto, (max-width: 855px) 100vw, 855px\" data-recalc-dims=\"1\" \/><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>It was about here that I discovered that my application wasn&#8217;t deploying the latest version because the publishing of the helm chart was taking longer than the time that github actions reached the <code>helm repo update<\/code><\/p><p>I added this update to the helm github action in main.yaml to fix that<\/p><\/blockquote>\n\n\n\n<pre class=\"wp-block-preformatted\">- name: Deploy<br>  uses: WyriHaximus\/github-action-helm3@v2<br>  with:<br>    exec: |<br>      helm repo add bullyrooks https:\/\/bullyrooks.github.io\/helm-charts\/<br>      helm repo update<br>      echo \"helm upgrade message-generator bullyrooks\/message-generator --install --version ${{ env.VERSION }}\"<br>      sleep 45s<br>      helm repo update<br>      helm upgrade message-generator bullyrooks\/message-generator --install --version ${{ env.VERSION }}<br>    kubeconfig: '${{ secrets.KUBECONFIG }}'<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"health-and-readiness-for-cloud-application\">Health and Readiness for Cloud Application<\/h2>\n\n\n\n<p>Go ahead and do the exact same setup for cloud-application.  Once you have that setup, we&#8217;re going to add some new health checks.<\/p>\n\n\n\n<p>When you deploy and run the health check you&#8217;re going to see that you have some additional health checks:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>        \"discoveryComposite\": {\r\n            \"status\": \"UP\",\r\n            \"components\": {\r\n                \"discoveryClient\": {\r\n                    \"status\": \"UP\",\r\n                    \"details\": {\r\n                        \"services\": &#91;\r\n                            \"cloud-application\"\r\n                        ]\r\n                    }\r\n                }\r\n            }\r\n        },\n...\n        \"kubernetes\": {\r\n            \"status\": \"UP\",\r\n            \"details\": {\r\n                \"nodeName\": \"gke-cloud-dev-b-1-b0b413d1-c9n4\",\r\n                \"podIp\": \"10.8.17.59\",\r\n                \"hostIp\": \"10.255.16.52\",\r\n                \"namespace\": \"bullyrooks\",\r\n                \"podName\": \"cloud-application-64dd9c6557-v2grm\",\r\n                \"serviceAccount\": \"default\",\r\n                \"inside\": true,\r\n                \"labels\": {\r\n                    \"app.kubernetes.io\/instance\": \"cloud-application\",\r\n                    \"app.kubernetes.io\/name\": \"cloud-application\",\r\n                    \"pod-template-hash\": \"64dd9c6557\"\r\n                }\r\n            }\r\n        },\n...\n        \"mongo\": {\r\n            \"status\": \"UP\",\r\n            \"details\": {\r\n                \"version\": \"4.4.12\"\r\n            }\r\n        },<\/code><\/pre>\n\n\n\n<p>The mongo one is built into the mongodb starter.  It will check the connection to the database to confirm connectivity.  The others come from the fabric 8 kubernetes framework.  One tells you the other services that are available via discovery.  The other tells you the status of the deployment so you can quickly debug.<\/p>\n\n\n\n<p>Now we&#8217;re going to create a new health check for the status of our dependent service (message-generator) and make the readiness status depend on the health of that service and the database.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"create-a-health-indicator\">Create a Health Indicator<\/h2>\n\n\n\n<p>in <code>com.bullyrooks.cloud_application.message_generator.client.dto<\/code> create a class called <code>HealthCheckDTO <\/code>with this content<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.bullyrooks.cloud_application.message_generator.client.dto;\r\n\r\nimport lombok.Data;\r\n\r\n@Data\r\npublic class HealthCheckDTO {\r\n    private String status;\r\n}\r\n<\/code><\/pre>\n\n\n\n<p><code>com.bullyrooks.cloud_application.message_generator.client<\/code> create a class called <code>MessageGeneratorHealthClient <\/code>with this content<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.bullyrooks.cloud_application.message_generator.client;\r\n\r\nimport com.bullyrooks.cloud_application.message_generator.client.dto.HealthCheckDTO;\r\nimport org.springframework.cloud.openfeign.FeignClient;\r\nimport org.springframework.http.MediaType;\r\nimport org.springframework.http.ResponseEntity;\r\nimport org.springframework.web.bind.annotation.GetMapping;\r\n\r\n@FeignClient(contextId = \"healthClient\", name = \"message-generator\")\r\npublic interface MessageGeneratorHealthClient {\r\n\r\n    @GetMapping(value = \"\/actuator\/health\",\r\n            produces = MediaType.APPLICATION_JSON_VALUE,\r\n            consumes = MediaType.APPLICATION_JSON_VALUE\r\n    )\r\n    ResponseEntity&lt;HealthCheckDTO> getHealth();\r\n}\r\n<\/code><\/pre>\n\n\n\n<p>This will create a client that uses our <code>message-generato<\/code>r service discovered through kubernetes to hit the health endpoint.  We only care about status, so that&#8217;s the only field we map into the DTO.<\/p>\n\n\n\n<p>Now add this content to <code>application.yaml<\/code><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">feign:<br>  client:<br>    config:<br>      healthClient:<br>        connectTimeout: 1000<br>        readTimeout: 1000<\/pre>\n\n\n\n<p>and in <code>application.yaml<\/code> update this clause<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>management:\r\n  endpoints:\r\n    web:\r\n      exposure:\r\n        include: \"*\"\r\n  endpoint:\r\n    health:\r\n      probes:\r\n        enabled: true\r\n      show-details: always\r\n      group:\r\n        readiness:\r\n          include: \"readinessState,mongo,messageGenerator\"\r\n<\/code><\/pre>\n\n\n\n<p>Here we&#8217;re configuring our new feign client to timeout quickly if it can&#8217;t reach the health endpoint.  Notice that the feign client contextId maps to the configuration.  This allows us to use a separate timeout configuration for this client.<\/p>\n\n\n\n<p>Now create a new package: <code>com.bullyrooks.cloud_application.config<\/code>.  Create a class called <code>MessageGeneratorHealth <\/code>and add this content<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.bullyrooks.cloud_application.config;\r\n\r\nimport com.bullyrooks.cloud_application.message_generator.client.MessageGeneratorHealthClient;\r\nimport com.bullyrooks.cloud_application.message_generator.client.dto.HealthCheckDTO;\r\nimport lombok.extern.slf4j.Slf4j;\r\nimport org.apache.commons.lang.StringUtils;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.boot.actuate.availability.AvailabilityStateHealthIndicator;\r\nimport org.springframework.boot.actuate.health.Health;\r\nimport org.springframework.boot.actuate.health.HealthIndicator;\r\nimport org.springframework.boot.actuate.health.Status;\r\nimport org.springframework.boot.availability.ApplicationAvailability;\r\nimport org.springframework.boot.availability.AvailabilityState;\r\nimport org.springframework.boot.availability.ReadinessState;\r\nimport org.springframework.http.ResponseEntity;\r\nimport org.springframework.stereotype.Component;\r\n\r\n@Component\r\n@Slf4j\r\npublic class MessageGeneratorHealthIndicator implements HealthIndicator {\r\n\r\n    @Autowired\r\n    MessageGeneratorHealthClient messageClient;\r\n\r\n    public Health health() {\r\n        Health.Builder status = Health.up();\r\n        try {\r\n            ResponseEntity&lt;HealthCheckDTO> healthCheckDTO = messageClient.getHealth();\r\n            log.info(\"health check response: {}\\n{}\", healthCheckDTO.getStatusCode(), healthCheckDTO.getBody());\r\n            if (!StringUtils.equals(\"UP\", healthCheckDTO.getBody().getStatus())) {\r\n                status = Health.outOfService();\r\n            }\r\n        }catch (Exception e){\r\n            log.error(\"error trying to get message generator health: {}\", e.getMessage(),e);\r\n            status = Health.outOfService();\r\n        }\r\n        return status.build();\r\n    }\r\n}\r\n\r\n<\/code><\/pre>\n\n\n\n<p><code>HealthIndicator <\/code>is a spring actuator interface that will automatically detect this class and add its <code>health()<\/code> check to the health endpoint results.  In this class we use our new client to make sure that the <code>m<\/code>essage-generator health endpoint returns <code>UP<\/code>.  If it doesn&#8217;t, we return <code>DOWN <\/code>for this check.  Additionally, the naming convention used for the application.yaml will be the name minus <code>HealthIndicator<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"testing-with-message-generator-up\">Testing with Message Generator Up<\/h2>\n\n\n\n<p>Message generator should already be running.  Hit the endpoint for your cloud-application health endpoint (<code>actuator\/health<\/code>).  You should see something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    \"status\": \"UP\",\n...\n        \"messageGenerator\": {\n            \"status\": \"UP\"\n        },\n...\n        \"readinessState\": {\n            \"status\": \"UP\"\n        },\n<\/code><\/pre>\n\n\n\n<p>and the readiness endpoint (<code>actuator\/health\/readines<\/code>s) should look like this<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\r\n    \"status\": \"UP\",\r\n    \"components\": {\r\n        \"messageGenerator\": {\r\n            \"status\": \"UP\"\r\n        },\r\n        \"mongo\": {\r\n            \"status\": \"UP\",\r\n            \"details\": {\r\n                \"version\": \"4.4.12\"\r\n            }\r\n        },\r\n        \"readinessState\": {\r\n            \"status\": \"UP\"\r\n        }\r\n    }\r\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"testing-with-message-generator-down\">Testing with Message Generator Down<\/h2>\n\n\n\n<p>Log into okteto and destroy the message-generator deployment.<\/p>\n\n\n\n<p>Hit your readiness endpoint (<code>\/actuator\/health\/readiness<\/code><strong>)<\/strong>, you should see something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>   {\r\n    \"status\": \"OUT_OF_SERVICE\",\r\n    \"components\": {\r\n        \"messageGenerator\": {\r\n            \"status\": \"OUT_OF_SERVICE\"\r\n        },\r\n        \"mongo\": {\r\n            \"status\": \"UP\",\r\n            \"details\": {\r\n                \"version\": \"4.4.12\"\r\n            }\r\n        },\r\n        \"readinessState\": {\r\n            \"status\": \"UP\"\r\n        }\r\n    }\r\n}<\/code><\/pre>\n\n\n\n<p>you can also see the changes in the \/actuator\/health endpoint<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    \"status\": \"OUT_OF_SERVICE\",\n...\n        \"messageGenerator\": {\r\n            \"status\": \"OUT_OF_SERVICE\"\n...\n        \"readinessState\": {\r\n            \"status\": \"UP\"\r\n        },<\/code><\/pre>\n\n\n\n<p><strong>I&#8217;m not sure why readinessState here looks UP<\/strong>.  However, you must be very careful with the readiness and liveness probes and kubernetes can take your service out of availability if they are failing.   <a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/current\/reference\/html\/actuator.html#actuator.endpoints.kubernetes-probes\">The docs are very specific about this<\/a>:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>As for the \u201creadiness\u201d probe, the choice of checking external systems must be made carefully by the application developers. For this reason, Spring Boot does not include any additional health checks in the readiness probe. If the\u00a0<a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/current\/reference\/html\/features.html#features.spring-application.application-availability.readiness\">readiness state of an application instance<\/a>\u00a0is unready, Kubernetes does not route traffic to that instance. Some external systems might not be shared by application instances, in which case they could be included in a readiness probe. Other external systems might not be essential to the application (the application could have circuit breakers and fallbacks), in which case they definitely should not be included. Unfortunately, an external system that is shared by all application instances is common, and you have to make a judgement call: Include it in the readiness probe and expect that the application is taken out of service when the external service is down or leave it out and deal with failures higher up the stack, perhaps by using a circuit breaker in the caller.<\/p><\/blockquote>\n\n\n\n<p>I do not recommend implementing it this way for our use case.  Cloud application is available when message generator is offline (you can provide a message and it should still work).  I&#8217;m only using this as an example of how to hook up readiness probes for dependent systems.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"entry-summary\">\nSpring offers a way to tell if your services and their dependent&hellip;\n<\/div>\n<div class=\"link-more\"><a href=\"https:\/\/bullyrooks.com\/index.php\/2022\/02\/13\/kube-cloud-pt3-health-indicators\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &ldquo;Kube Cloud Pt3 | Health Indicators&rdquo;<\/span>&hellip;<\/a><\/div>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41],"tags":[163,80,43],"course":[161],"class_list":["post-1264","post","type-post","status-publish","format-standard","hentry","category-software-development","tag-actuator","tag-kubernetes","tag-spring-boot","course-kubernetes-application-hosted-in-the-cloud-pt-3","entry"],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":1258,"url":"https:\/\/bullyrooks.com\/index.php\/2022\/02\/13\/kube-cloud-pt3-rest-interaction\/","url_meta":{"origin":1264,"position":0},"title":"Kube Cloud Pt3 | REST Interaction","author":"Bullyrook","date":"February 13, 2022","format":false,"excerpt":"Now that we've got a new service, we're going to make it discoverable via kubernetes and call it from the cloud application service. Enable Kubernetes Features Let's start a new branch in our cloud_application project $ git checkout -b kube Switched to a new branch 'kube' Edit the pom.xml and\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":1356,"url":"https:\/\/bullyrooks.com\/index.php\/2022\/02\/27\/kube-cloud-pt5-create-an-event-consumer\/","url_meta":{"origin":1264,"position":1},"title":"Kube Cloud Pt5 | Create an Event Consumer","author":"Bullyrook","date":"February 27, 2022","format":false,"excerpt":"Now that we've got messages being published to kafka, we are going to need to build our consumer that receives those events and stores them into the mongo database. Go ahead and create a new repository called message-repository according to the microservice startup course here. This is the pom.xml that\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-49.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-49.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-49.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1242,"url":"https:\/\/bullyrooks.com\/index.php\/2022\/02\/13\/kube-cloud-pt3-synchronous-service-interaction\/","url_meta":{"origin":1264,"position":2},"title":"Kube Cloud Pt3 | Synchronous Service Interaction","author":"Bullyrook","date":"February 13, 2022","format":false,"excerpt":"In this course I'm going to show you how to make another spring boot microservice (message-generator), deploy it with our first service (cloud-application). I'll show how cloud-application service can discover message-generator via kubernetes services, call an endpoint in message-generator with a feign based REST client as well as how to\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-45.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-45.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-45.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-45.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-45.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":1278,"url":"https:\/\/bullyrooks.com\/index.php\/2022\/02\/19\/kube-cloud-pt4-logging\/","url_meta":{"origin":1264,"position":3},"title":"Kube Cloud Pt4 | Logging","author":"Bullyrook","date":"February 19, 2022","format":false,"excerpt":"Add Structured Logging Structured logging means that we're going to log our output in json format. This is extremely useful because it allows tools to easily parse the json to make the individual log message attributes available for searching and allows you to control the presentation (highlight signal, reduce noise).\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-7.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":829,"url":"https:\/\/bullyrooks.com\/index.php\/2020\/03\/30\/simple-spring-boot-service-to-kubernetes-application-step-15-34e1bba8351b\/","url_meta":{"origin":1264,"position":4},"title":"Messaging and Event Driven Design","author":"Bullyrook","date":"March 30, 2020","format":false,"excerpt":"In order publish messages, we need a message broker and add some logic to use the message broker. We\u2019re going to use a cloud based SaaS service as a message broker and use spring cloud stream to interact with it. Setup the Message\u00a0Broker We\u2019ll need a message broker in order\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1301,"url":"https:\/\/bullyrooks.com\/index.php\/2022\/02\/20\/kube-cloud-pt4-metrics\/","url_meta":{"origin":1264,"position":5},"title":"Kube Cloud Pt4 | Metrics","author":"Bullyrook","date":"February 20, 2022","format":false,"excerpt":"Logz.io uses prometheus for metrics. Go ahead and enable metrics collection in logz.io. Navigate to send your metrics Search for java Choose java custom metrics via micrometer. We're using micrometer because its integrated into spring boot and available via actuator, which we're already using. The important part here is that\u2026","rel":"","context":"In &quot;General&quot;","block_context":{"text":"General","link":"https:\/\/bullyrooks.com\/index.php\/category\/general\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-22.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts\/1264","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/comments?post=1264"}],"version-history":[{"count":5,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts\/1264\/revisions"}],"predecessor-version":[{"id":1275,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts\/1264\/revisions\/1275"}],"wp:attachment":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/media?parent=1264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/categories?post=1264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/tags?post=1264"},{"taxonomy":"course","embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/course?post=1264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}