{"id":13760835,"url":"https://github.com/Sixt/ja-micro","last_synced_at":"2025-05-10T11:32:02.342Z","repository":{"id":99879178,"uuid":"80715992","full_name":"Sixt/ja-micro","owner":"Sixt","description":"Lightweight framework for building java microservices","archived":true,"fork":false,"pushed_at":"2020-01-30T08:48:55.000Z","size":1053,"stargazers_count":613,"open_issues_count":8,"forks_count":58,"subscribers_count":61,"default_branch":"master","last_synced_at":"2024-08-04T13:05:31.841Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sixt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-02-02T10:47:26.000Z","updated_at":"2024-06-07T22:09:00.000Z","dependencies_parsed_at":"2023-05-10T21:30:46.790Z","dependency_job_id":null,"html_url":"https://github.com/Sixt/ja-micro","commit_stats":null,"previous_names":[],"tags_count":101,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sixt%2Fja-micro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sixt%2Fja-micro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sixt%2Fja-micro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sixt%2Fja-micro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sixt","download_url":"https://codeload.github.com/Sixt/ja-micro/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224957862,"owners_count":17398493,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T13:01:23.641Z","updated_at":"2024-11-16T18:31:37.436Z","avatar_url":"https://github.com/Sixt.png","language":"Java","funding_links":[],"categories":["Java","开发框架","Service Toolkits"],"sub_categories":["Java VM"],"readme":"# Ja-micro [![License](https://img.shields.io/:license-apache-blue.svg)](https://opensource.org/licenses/Apache-2.0) \n\nJa-micro is a lightweight Java framework for building microservices.\n\n## Introduction ##\n\nJa-micro is a framework that allows developers to easily develop microservices in \nJava. It was developed at Sixt, primarily over the course of 2016, during a push to \ncreate a new platform. That platform was started with a goal of supporting two primary \nlanguages, being Golang and Java. \n\nWe use [Go Micro](https://github.com/micro) as our framework for our Go services, so a \nprimary concern for this framework is to be compatible with Micro. They diverge a bit in \ncapabilities and methodologies, but they are indeed compatible. \n\nThe framework takes care of many of the concerns so that developers can simply \nfocus on the functionality of their services instead.\n\n[See the wiki](https://github.com/Sixt/ja-micro/wiki) to get started.\n\n## Features ##\n\n* Simply build service as docker container or fat jar.\n* Configuration from environment, command-line and external configuration services.\n* Standardized json logging.\n* Standardized metrics reporting\n* Simple interface for calling endpoints on other services and handling errors from them.\n* Client-side load-balancer\n* Simple interface for a service to support health checks.\n* Database migrations built-in.\n* Simplified event-handling using Kafka.\n* Pluggable service registry to register and discover service instances.\n* Compatible with Go Micro to allow choice of implementation language.\n* Guice dependency injection for ease of implementation and testing scenarios.\n* Components to create service integration testing scenarios.\n\n## Details\n\n### Service Registry ###\n\nThe service registry is pluggable with different backends (consul, etc.) The purpose\nto for each service instance (which may be coming up on a rather anonymous IP address\nand random port) to register so that other instances can locate it. It is also by\nextension, available for services to use to locate instances of other services.\nThe service information contains specially-formatted tags which contain information\nabout the format of the request and response messages for each endpoint, and other\ntags.\n\n### Client-side Load-balancer ###\n\nThere is a client-side load-balancer in place behind the facade of the `RpcClient`.\nThis interacts with the service registry to track instances of services a service wants\nto interact with, tracks their state of health in order to know whether the instances\nshould receive requests, and tracks the response results of each rpc call in order to\nmaintain 'circuit breakers' to limit exposure to non-healthy service instances.\n\n### RpcClient and Error Handling ###\n\nIn order to allow a service to call other services, there is support to easily create `RpcClient`s.\nAn `RpcClient` is an object that abstracts an rpc endpoint of another service.  One can create an `RpcClient`\nby using the `RpcClientFactory`. Once one has an `RpcClient`, calling another service endpoint is as simple\nas calling the `callSynchronous` method (a future version of the framework will also\nsupport asynchronous calls) with a protobuf request message, and it will return a protobuf response\nmessage. \n\nThe timeout policy, the retry policy, and the error-handling are all handled by the client. By default,\nwe have said that the default retry policy should be to retry a failed request one time, if the response is\nretriable. In a future release, we will add support for time budgeting, where a client of a service can set\nhow much time is allowed to service the whole request. For now, we have a static policy\nwith a default timeout of 1000ms, and this can be customized per client. \n\nThe `RpcCallException` class defines all of\nour exception categories, their default retriable setting, and what the resulting HTTP status code is (when using\nan HTTP transport). When one service calls another (client calling server), if a server throws an exception\nduring processing the response, the exception is transparently transported back to the client and can be\nrethrown on the client-side (ignoring the retry aspect here).\n\nDefault RpcClient retry policy (1) can be overridden with setting 'rpcClientRetries'.\nDefault RpcClient timeout policy (1000ms) can be overridden with setting 'rpcClientTimeout'.\n\n### Health Checks ###\n\nEvery few seconds, the health state for a service instance is reported to the service\nregistry plugin. Using annotations, there is support for a service developer to easily\nhook into health checking to mark a service instance as unhealhty. There is also an\ninterface to immediately change the health state of an instance.\n\n### Configuration Handling ###\n\nFor any component in a service requiring configuration, it can simply get a `ServiceProperties`\nobject injected into it, and request the configuration properties from it. Properties are\nlocated from three locations: command-line, environment variables, and configuration plugin.\nThey are applied in that order. The same property with a different value from a later source\noverwrites the earlier source. The configuration plugin provides the ability to do long-polling so \nthat each service can get real-time updates to changes of the configuration from arbitrary sources. \nThere are hooks for service components to get real-time notifications of configuration changes.\n\n### Logging ###\n\nThere is standardized logging in place. The log records are json objects, and `Marker`s can\nbe used to dynamically create properties on those objects. The log format can be completely customized.\n\n### Metrics ###\n\nThere is standardized metric handling in place. This is heavily opinionated to Sixt's\ninfrastructure, and uses metrics formatted in a specific format and sent to an influx agent\nto be reported back to a central influxdb cluster.  The metrics reporting is pluggable to \nsupport reporting metrics in any desired format to any desired destination.\n\n### Kafka Events ###\n\nThere are factories/builders in place to easily create publishers and subscribers for\ntopics in Kafka.\n\n### Output Artifacts ###\n\nOne can build a shadow jar (fat jar - all dependencies included), or a docker image. One might\nuse the shadow jar for developer testing. The shadow jar is a dependency of the docker image\ntasks as well. To start a service in a debugger, use the `JettyServiceBase` as a main class.\n\n### Database Migrations ###\n\nThere is currently support for Flyway database migrations, which supports many different\nSQL databases. This support extends into carefully controlling the service lifecycle\nand health checks. A future version should support basic migration support for DynamoDB\ninstances.\n\n### Dependency Injection ###\n\nDependency injection is heavily used in Ja-micro. It is strictly supporting Guice.\n\n### Service Integration Testing ###\n\nWe heavily use automation at Sixt in our microservice projects. To support this, the framework \ngives the ability to developers to automate service integration tests. What this means is \nthat core infrastructure dependencies (for example, on one service, this is consul, \npostgres, zookeeper and kafka) and the\nservice itself are started as containers under docker-compose. Additionally, to\neliminate the problem that would arise of starting containers for every other service\ndependency (and their dependencies, etc.), there exists a class called `ServiceImpersonator`\nthat can serve as a complete service mock, available in service registry and serving\nreal rpc requests. However, the developer maps the requests and responses instead\nof a real instance serving those requests.\n\n##  Compatibility ##\n\nJa-micro is meant to keep compatibility so that service developers can easily choose\nbetween developing a service in Java or Go. Other languages can also be supported by\nusing the Go Micro sidecar.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSixt%2Fja-micro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSixt%2Fja-micro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSixt%2Fja-micro/lists"}