{"id":13511608,"url":"https://github.com/megaease/easemesh","last_synced_at":"2025-04-04T11:11:03.947Z","repository":{"id":39713093,"uuid":"334851928","full_name":"megaease/easemesh","owner":"megaease","description":"A service mesh implementation for connecting,  control, and observe services in spring-cloud.","archived":false,"fork":false,"pushed_at":"2024-04-01T02:03:42.000Z","size":6132,"stargazers_count":514,"open_issues_count":13,"forks_count":61,"subscribers_count":20,"default_branch":"main","last_synced_at":"2025-03-28T10:04:53.955Z","etag":null,"topics":["go","kubernetes","mesh","microservice","microservices","observability","service","service-governance","service-mesh","servicemesh","spring-cloud","traffic-splitting"],"latest_commit_sha":null,"homepage":"https://megaease.com/easemesh","language":"Go","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/megaease.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":"docs/Roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-01T06:24:29.000Z","updated_at":"2025-03-16T09:11:28.000Z","dependencies_parsed_at":"2024-06-18T18:16:45.568Z","dependency_job_id":"f7125642-8df1-4acc-8960-8311450dcf26","html_url":"https://github.com/megaease/easemesh","commit_stats":{"total_commits":219,"total_committers":15,"mean_commits":14.6,"dds":0.680365296803653,"last_synced_commit":"21ffa27db0d5c1b1e2fac8bfb7ac3ab090e2ea56"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/megaease%2Feasemesh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/megaease%2Feasemesh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/megaease%2Feasemesh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/megaease%2Feasemesh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/megaease","download_url":"https://codeload.github.com/megaease/easemesh/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247166168,"owners_count":20894654,"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":["go","kubernetes","mesh","microservice","microservices","observability","service","service-governance","service-mesh","servicemesh","spring-cloud","traffic-splitting"],"created_at":"2024-08-01T03:01:00.112Z","updated_at":"2025-04-04T11:11:03.924Z","avatar_url":"https://github.com/megaease.png","language":"Go","funding_links":[],"categories":["Go","Service Mesh"],"sub_categories":[],"readme":"# EaseMesh\n\nEaseMesh is a service mesh that is compatible with the Spring Cloud ecosystem. It is based on [Easegress](https://github.com/megaease/easegress) for the sidecar of service management and [EaseAgent](https://github.com/megaease/easeagent) for the monitor of service observing.\n\n\u003ca href=\"https://megaease.com/easemesh\"\u003e\n    \u003cimg src=\"./imgs/easemesh.svg\"\n        alt=\"EaseMesh logo\" title=\"EaseMesh\" height=\"175\" width=\"175\" align=\"right\"/\u003e\n\u003c/a\u003e\n\n- [EaseMesh](#easemesh)\n  - [1. Purposes](#1-purposes)\n  - [2. Principles](#2-principles)\n  - [3. Architecture](#3-architecture)\n  - [4. Features](#4-features)\n  - [5. Dependent Projects](#5-dependent-projects)\n  - [6. Quick Start](#6-quick-start)\n    - [6.1 Environment Requirement](#61-environment-requirement)\n    - [6.2 Sanity Checking](#62-sanity-checking)\n    - [6.3 Installation](#63-installation)\n  - [7. Demonstration](#7-demonstration)\n    - [7.1 Start PetClinic in EaseMesh](#71-start-petclinic-in-easemesh)\n      - [7.1.1 Step 1: Apply mesh configuration](#711-step-1-apply-mesh-configuration)\n      - [7.1.2 Step 2: Create namespace](#712-step-2-create-namespace)\n      - [7.1.3 Step 3: Setup Database](#713-step-3-setup-database)\n      - [7.1.4 Step 4: Apply petclinic stack](#714-step-4-apply-petclinic-stack)\n      - [7.1.5 Get exposed port of `EaseMesh ingress` service](#715-get-exposed-port-of-easemesh-ingress-service)\n      - [7.1.6 Step 5: Configure reverse proxy](#716-step-5-configure-reverse-proxy)\n        - [7.1.6.1 Config reverse proxy via Easegress](#7161-config-reverse-proxy-via-easegress)\n        - [7.1.6.2 Config reverse proxy via Nginx](#7162-config-reverse-proxy-via-nginx)\n    - [7.2 Canary Deployment](#72-canary-deployment)\n      - [7.2.1  Step 1: Coloring traffic](#721--step-1-coloring-traffic)\n      - [7.2.2 Step 2: Apply canary configuration of the EaseMesh](#722-step-2-apply-canary-configuration-of-the-easemesh)\n      - [7.2.3 Step 3:  Prepare a canary version of the application](#723-step-3--prepare-a-canary-version-of-the-application)\n      - [7.2.4 Step 4: Build canary image](#724-step-4-build-canary-image)\n      - [7.2.5 Step 5. Deploy canary version](#725-step-5-deploy-canary-version)\n      - [7.2.6 Step 6: Sending coloring traffic](#726-step-6-sending-coloring-traffic)\n    - [7.3 Clean](#73-clean)\n  - [8. Roadmap](#8-roadmap)\n  - [9. Contributing](#9-contributing)\n  - [10. License](#10-license)\n  - [11. User Manual](#11-user-manual)\n\n## 1. Purposes\n\nWhy do we reinvent another wheel?\n\n- **Service mesh compatible with Spring Cloud ecosystem:** Micro-service in Spring Cloud ecosystem has its own service registry/discovery components. It is quite different from Kubernetes ecosystem using DNS for service discovery. The major Service Mesh solution (e.g. Istio) using the Kubernetes domain technology. It is painful and conflicted with Java Spring Cloud ecosystem. EaseMesh aims to make Service Mesh compatible with Java Spring Cloud completely.\n\n- **Integrated Observability:** Currently Kubernetes-based service mesh only can see the ingress/egress traffic, and it has no idea what's happened in service/application. So, combining with Java Agent technology, we can have the full capability to observe everything inside and outside of service/application.\n\n- **Sophisticated capability of traffic split:**  The EaseMesh has the sophisticated capability of traffic split, it can split traffic of a request chain into not only first service but also last. The capability could be applied in the canary deployment, online production testing scenarios.\n\n\u003e Shortly, **the EaseMesh leverages the Kubernetes sidecar and Java Agent techniques to make Java applications have service governance and integrated observability without change a line of source code**.\n\n## 2. Principles\n\n- **Spring Cloud Compatibility:** Spring Cloud domain service management and resilient design.\n- **No Code Changes:** Using sidecar \u0026 Java-agent for completed service governance and integrated observability.\n- **Service Insight:** Service running metrics/tracing/logs monitoring.\n\n## 3. Architecture\n\n![The architecture diagram](./imgs/architecture.png)\n\n## 4. Features\n\n- **Non-intrusive Design**: Zero code modification for Java Spring Cloud application migration, only small configuration update needed.\n- **Java Register/Discovery**: Compatible with popular Java Spring Cloud ecosystem's Service registry/discovery.\n  - **Multiple tenants(namespace)** Supporting multiple tenants' service registration, isolate services from different tenants.\n  - **Share (global) tenant** Support share tenants, all services have visibility to the service registered in the global tenant.\n  - **Compatible**\n    - Be compatible with the Eureka registry.\n    - Be compatible with the Consul registry.\n    - Be compatible with the Nacos registry.\n  - **Extensibility** Support registering services with metadata.\n- **Resource Management**: Rely on Kubernetes platform for CPU/Memory resources management.\n- **Traffic Orchestration**\n\t- **Rich Routing Rules:** Exact path, path prefix, regular expression of the path, method, headers.\n  - **Traffic Splitting** Coloring \u0026 Scheduling east-west and north-south traffic to configured services.\n  - **LoadBalance** Support Round Robin, Weight Round Robin, Random, Hash by Client IP Address, Hash by HTTP Headers.\n- **Resilience**: Including Timeout/CircuitBreaker/Retryer/Limiter, completely follow sophisticated resilience design.\n\t- **Resilience\u0026Fault Tolerance**\n\t\t- **Circuit breaker:** Temporarily blocks possible failures.\n\t\t- **Rate limiter:** Limits the rate of incoming requests.\n\t\t- **Retryer:** Repeats failed executions.\n\t\t- **Time limiter:** Limits the duration of execution.\n  - **Chaos engineering**\n    - **Fault injection** *Working in progress.*\n    - **Delay injection** *Working in progress.*\n- **Observability**:\n  - **Logs**\n    - **Access Logs** Generate HTTP access log for all requests per service.\n    - **Application log** Automatically inject the tracing context into log data.\n  - **Tracing**\n    - **JDBC** Tracing for invocation of the JDBC.\n    - **HTTP Request** Tracing for HTTP RPC.\n    - **Kafka** Tracing for messages delivered by Kafka.\n    - **Redis** Tracing for Redis cache accessing.\n    - **RabbitMQ** Tracing for messages delivered by the RabbitMQ.\n    - **Sampling**\n      - Support probabilistic sampling.\n      - Support QPS sampling.\n  - **Metrics**\n    - **HTTP Request** Reporting throughput latency per URL.\n    - **JDBC**  Reporting throughput and latency per SQL.\n    - **Kafka** Reporting throughput and latency per consumer, producer, and topic.\n    - **Redis** Reporting throughput and latency per method.\n    - **RabbitMQ** Reporting throughput and latency per topic.\n- **Security**\n  - **mTLS** *Working in progress.*\n  - **mTLS Enforcement** *Working in progress.*\n  - **External CA certificate** *Working in progress.*\n  - **Service-to-Service Authorization Rules** *Working in progress.*\n\n\u003e The throughput is represented by m1, m5, m15\n\u003e The latency is represented by P99, P98, P95, P90, P80, P75, P50, etc...\n\n## 5. Dependent Projects\n\n1. [EaseAgent](https://github.com/megaease/easeagent)\n2. [Easegress](https://github.com/megaease/easegress)\n\n## 6. Quick Start\n\n### 6.1 Environment Requirement\n\n- Linux kernel version 4.15+\n- Kubernetes version 1.18+\n- MySQL version 5.7+\n\n### 6.2 Sanity Checking\n\n- Running `kubectl get nodes` to check your Kubernetes cluster's healthy.\n\n### 6.3 Installation\n\nPlease check out [install.md](./docs/install.md) to install EaseMesh.\n\n## 7. Demonstration\n\n- [Spring Cloud PetClinic](https://github.com/spring-petclinic/spring-petclinic-cloud) microservice example.\n\n- It uses Spring Cloud Gateway, Spring Cloud Circuit Breaker, Spring Cloud Config, Spring Cloud Sleuth, Resilience4j, Micrometer and Eureka Service Discovery from Spring Cloud Netflix technology stack.\n\n![The topology migration diagram](imgs/topology-migration.png)\n\nPrepare the `emctl`\n\n```bash\ngit clone https://github.com/megaease/easemesh\ncd emctl \u0026\u0026 make\nexport PATH=$(pwd)/bin:${PATH}\n```\n\n### 7.1 Start PetClinic in EaseMesh\n\n#### 7.1.1 Step 1: Apply mesh configuration\n\nApply the EaseMesh configuration files\n\n```bash\nemctl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/mesh-conf/a-pet-tenant.yaml\nemctl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/mesh-conf/api-gateway.yaml\nemctl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/mesh-conf/customers.yaml\nemctl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/mesh-conf/ingress.yaml\nemctl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/mesh-conf/vets.yaml\nemctl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/mesh-conf/visits.yaml\n```\n\n#### 7.1.2 Step 2: Create namespace\n\nleverage kubectl to create `spring-petclinic` namespace\n\nWe support to automatically inject sidecar and the JavaAgent when a deployment was created or updated in an interested namespace. So you need to create a namespace with a specific label, we are prepared a spring-petclinic namespace, you can create it via:\n\n```bash\nkubectl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/namespace/spring-petclinic.yaml\n```\n\n#### 7.1.3 Step 3: Setup Database\n\nThe pet clinic demo needs to access database, the default is memory database. But in the EaseMesh quick start, you could to use memory database by default.\n\n\u003eIf you want to use the MySQL database, you could create the DB table schemes and import records from [PetClinic example](https://github.com/spring-projects/spring-petclinic/tree/main/src/main/resources/db/mysql) to set up yours.\n\n#### 7.1.4 Step 4: Apply petclinic stack\n\nDeploy petclinic resources to k8s cluster, we have developed an [operator](./operator/README.md) to manage the custom resource (MeshDeployment) of the EaseMesh. `Meshdeployment` contains a K8s' complete deployment spec and a piece of extra information about the service.\n\n\u003e The Operator of the EaseMesh will automatically inject a sidecar to pod and a JavaAgent into the application's JVM\n\nNow, we support injecting the JavaAgent and sidecar into the native deployment, but you need to explicitly specify the service name in the Deployment spec via `mesh.megaease.com/service-name: \"{service-name}\"` of the annotation. EaseMesh has a [`admission control`](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/) server, which will watch Create/Update operation of Deployments in the specified namespace. If a deployment with `mesh.megaease.com/service-name` annotation was created in the specific namespace (labeled with key `mesh.megaease.com/mesh-service`), the admission control server will mutate the deployment spec and inject the sidecar and the JavaAgent.\n\n```bash\nkubectl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/deployments/01-vets.yaml\nkubectl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/deployments/02-visits.yaml\nkubectl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/deployments/03-customers.yaml\nkubectl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/deployments/04-api-gateway.yaml\n```\n\n\u003e ATTENTION: There is a ConfigMap spec in yaml file, if you to want to use the MySQL database, you need to change it per your environments.\n\n#### 7.1.5 Get exposed port of `EaseMesh ingress` service\n\n```bash\nkubectl get service -n easemesh easemesh-ingress-service\n```\n\u003e **ATTENTION**: From the output, you may notice exposed port of the Ingress service. If you needn't use reverse proxy service, you can directly access pet-clinic application via http://{your_host}:{exposed_port}/\n\n#### 7.1.6 Step 5: Configure reverse proxy\n\n\u003e **ATTENTION**: The step is optional. It can be omitted when you have no requirements about reverse proxy.\n\n##### 7.1.6.1 Config reverse proxy via Easegress\n\n\u003e **ATTENTION**: Only for scenarios that the Easegress acts as the role of reverse proxy service\n\nIf you leverage the [Easegress](https://github.com/megaease/easegress) as a reverse proxy service, the following configuration can be applied.\n\nHTTP Server spec (file name: http-server.yaml):\n\n```yaml\nkind: HTTPServer\nname: spring-petclinic-example\nport: 443\nhttps: true\nkeepAlive: true\nkeepAliveTimeout: 75s\nmaxConnection: 10240\ncacheSize: 0\ncerts:\n  key: {add your certs information to here}\nrules:\n  - paths:\n    - pathPrefix: /\n      backend: http-petclinic-pipeline\n```\n\nHTTP Pipeline spec (file name: http-petclinic-pipeline.yaml):\n\n```yaml\nname: http-petclinic-pipeline\nkind: HTTPPipeline\nflow:\n  - filter: requestAdaptor\n  - filter: proxy\nfilters:\n  - name: requestAdaptor\n    kind: RequestAdaptor\n    method: \"\"\n    path: null\n    header:\n      del: []\n      set:\n        Host: \"{you host name, can be omitted}\"\n        X-Forwarded-Proto: \"https\"\n        Connection: \"upgrade\"\n      add:\n        Host: \"{you host name, can be omitted}\"\n  - name: proxy\n    kind: Proxy\n    mainPool:\n      servers:\n      - url: http://{node1_of_k8s_cluster}:{port_exposed_by_ingress_service}\n      - url: http://{node2_of_k8s_cluster}:{port_exposed_by_ingress_service}\n      loadBalance:\n        policy: roundRobin\n```\n\nChange contents in `{}` as per your environment, and apply it via Easegress client command tool `egctl`:\n\n```bash\negctl apply -f http-server.yaml\negctl apply -f http-petclinic-pipeline.yaml\n```\n\n\u003e **egctl** is the client command line of the Easegress\n\nVisiting PetClinic website with `$your_domain/#!/welcome`\n\n##### 7.1.6.2 Config reverse proxy via Nginx\n\n\u003e **ATTENTION**: Only for scenarios that the Nginx acts as the role of reverse proxy service\n\nif you leverage the Nginx as a reverse proxy service, the following configuration should be added.\n\nThen configure the NodPort IP address and port number into your traffic gateway's routing address, e.g, add config to NGINX:\n\n```plain\nlocation /pet/ {\n    proxy_pass http://{node1_of_k8s_cluster}:{port_exposed_by_ingress_service}/;\n}\n```\n\n\u003e **ATTENTION:**  that the PetClinic website should be routed by the  `/`  subpath, or it should use  `NGINX`'s replacing response content feature for correcting resource URL:\n\n```plain\nlocation /pet/ {\n    proxy_pass http://{node1_of_k8s_cluster}:{port_exposed_by_ingress_service/;\n    sub_filter 'href=\"/' 'href=\"/pet/';\n    sub_filter 'src=\"/' 'src=\"/pet/';\n    sub_filter_once  off;\n}\n```\n\nVisiting PetClinic website with `$your_domain/pet/#!/welcome`.\n\n### 7.2 Canary Deployment\n\nCanary deployment demonstrates how to route coloring traffic (request) to a canary version of the specific service.\n\n![EaseMesh Canary topology](./imgs/canary-deployment.png)\n\n- `Customer Service (v2)` is the canary version service.\n- The line of red color in the diagram represents coloring traffic (request).\n- The coloring traffic is correctly routed into canary version service after it has passed through the first service (API Gateway).\n\n#### 7.2.1  Step 1: Coloring traffic\n\nColoring traffic with HTTP header `X-Canary: lv1` by using Chrome browser's **[ModHeader](https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj?hl=en)** plugin. Then EaseMesh will route this colored traffic into the Customer service's canary version instance.\n\n#### 7.2.2 Step 2: Apply canary configuration of the EaseMesh\n\nApply mesh configuration file:\n\n```bash\nemctl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/canary/customer-canary.yaml`\n```\n\n#### 7.2.3 Step 3:  Prepare a canary version of the application\n\n\u003e **ATTENTION**  You can skip the step, we have provides the canary image to docker hub `megaease/spring-petclinic-customers-service:canary` you can found it in the docker hub.\n\nDeveloping a canary version of Customer service to add an extra suffix to the city field for each record.\n\n```diff\ndiff --git a/spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/model/Owner.java b/spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/model/Owner.java\nindex 360e765..cc2df3d 100644\n--- a/spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/model/Owner.java\n+++ b/spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/model/Owner.java\n@@ -99,7 +99,7 @@ public class Owner {\n    }\n\n    public String getAddress() {\n-        return this.address;\n+        return this.address + \" - US\";\n    }\n\n    public void setAddress(String address) {k\n```\n\n#### 7.2.4 Step 4: Build canary image\n\n\u003e **ATTENTION**  You can skip the step, we have provides the canary image to docker hub `megaease/spring-petclinic-customers-service:canary` you can found it in the docker hub.\n\nBuilding the canary Customer service's image, and update image version in `https://github.com/megaease/easemesh-spring-petclinic/blob/main/canary/customers-service-deployment-canary.yaml`. Or just use our default canary image which already was in it.\n\n#### 7.2.5 Step 5. Deploy canary version\n\nBeing similar to [7.1.4](#714-step-3-apply-petclinic-stack),  we leverage kubectl to deploy the canary version of the `Deployment`\n\n```bash\nkubectl apply -f https://raw.githubusercontent.com/megaease/easemesh-spring-petclinic/main/canary/customers-service-deployment-canary.yaml`\n```\n\n\u003e **ATTENTION**: There is a ConfigMap spec in echo yaml spec, it describes how to connect the database for applications. You need to change its contents for your environment.\n\n#### 7.2.6 Step 6: Sending coloring traffic\n\nTurning on the chrome **ModHeader** plugin to color the traffic, then visit PetClinic website. You can see the change to the table which adds an \"-US\" suffix to every city record.\n\n  ![plugin](./imgs/chrome_plugin.png)\n\n\u003e [ModHeader](https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj?hl=en) is a chrome extension, we use it solely for demonstrating coloring the requests.\n\n### 7.3 Clean\n\n- Run `kubectl delete namespace spring-petclinic`.\n- Run\n\n```bash\nemctl delete ingress pet-ingress\nemctl delete service api-gateway\nemctl delete service customers-service\nemctl delete service vets-service\nemctl delete service visits-service\nemctl delete tenant pet\n```\n\n## 8. Roadmap\n\nSee [EaseMesh Roadmap](./docs/Roadmap.md) for details.\n\n## 9. Contributing\n\nSee [MegaEase Community](https://github.com/megaease/community) to follow our contributing details.\n\n## 10. License\n\nEaseMesh is under the Apache 2.0 license. See the [LICENSE](./LICENSE) file for details.\n\n## 11. User Manual\n\nSee [EaseMesh User Manual](./docs/user-manual.md) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmegaease%2Feasemesh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmegaease%2Feasemesh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmegaease%2Feasemesh/lists"}