{"id":49815465,"url":"https://github.com/leiwei2094/iris-java","last_synced_at":"2026-05-29T21:00:50.249Z","repository":{"id":44482626,"uuid":"110191629","full_name":"leiwei2094/iris-java","owner":"leiwei2094","description":"轻量级，微内核加插件机制，基于Java的RPC框架。可看成是mini版的Dubbo。提供服务注册，发现，负载均衡，支持API调用，Spring集成和Spring Boot starter使用。","archived":false,"fork":false,"pushed_at":"2024-07-24T13:28:34.000Z","size":152,"stargazers_count":111,"open_issues_count":0,"forks_count":45,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-07-24T15:32:51.580Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leiwei2094.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}},"created_at":"2017-11-10T02:20:46.000Z","updated_at":"2024-07-24T13:28:38.000Z","dependencies_parsed_at":"2023-01-20T06:45:46.679Z","dependency_job_id":null,"html_url":"https://github.com/leiwei2094/iris-java","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/leiwei2094/iris-java","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leiwei2094%2Firis-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leiwei2094%2Firis-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leiwei2094%2Firis-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leiwei2094%2Firis-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leiwei2094","download_url":"https://codeload.github.com/leiwei2094/iris-java/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leiwei2094%2Firis-java/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33670211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":"2026-05-13T06:00:43.974Z","updated_at":"2026-05-29T21:00:50.239Z","avatar_url":"https://github.com/leiwei2094.png","language":"Java","funding_links":[],"categories":["开发框架"],"sub_categories":["RPC框架"],"readme":"# iris\n\n一个基于Java的RPC框架。目前可以看成是mini版的Dubbo。有注册中心，提供服务的注册，发现和负载均衡。\n\n* 网络通信: Netty4\n* 注册中心: etcd，可扩展\n* 动态代理: byte-buddy\n* 序列化: Protobuff(Protostuff)\n* 可以脱离Spring，提供API调用。\n* 集成Spring，提供XML，Java配置\n* 提供Spring Boot Starter\n* 提供SPI机制，实现微内核加插件的架构。实现可扩展，开发者可以为iris开发组件，以插件的形式集成到iris中。插件的加载使用另一个微容器框架见[coco](https://github.com/vangoleo/coco)项目。该项目fork于阿里的[cooma](https://github.com/alibaba/cooma)。\n\n# Todo:\n* 支持优雅停机，不依赖Spring和Web容器。\n* 支持服务延迟暴露\n* 支持超时和重试配置\n* 添加监控系统，使用Prometheus\n* 更好的支持容器环境\n\n# How to use\niris支持以下使用方式:    \n1. 原生API形式，不依赖Spring,非Spring项目也可以使用\n2. Spring配置方式，和Spring很好的集成\n3. Spring Boot配置方式，提供了一个spring boot starter，以自动配置，快速启动\n\n# API使用\nIris核心代码不依赖Spring，可脱离Spring使用。        \n1. 启动etcd注册中心\n2. 编写一个接口IHelloService\n```java\npublic interface IHelloService {\n    String hello(String name);\n}\n```\n3. 编写一个IHelloService的实现\n```java\npublic class HelloService implements IHelloService {\n    @Override\n    public String hello(String name){\n        return \"Hello, \" + name;\n    }\n}\n```\n4. 启动Server\n```java\nIRegistry registry = new EtcdRegistry(\"http://127.0.0.1:2379\");\nRpcServer server = new RpcServer(registry)\n        .port(2017)\n        .exposeService(IHelloService.class,new HelloService());\nserver.run();\n```\n5. 启动client\n```java\nRpcClient client = new RpcClient(registry);\nIHelloService helloService = client.create(IHelloService.class);\nString s = helloService.hello(\"leo\");\nSystem.out.println(s);   // hello, leo\n```\n6. 停止server\n```text\n因为服务没有provider，client报错找不到provider        \n```\n7. 启动server        \n```text\nserver启动后，会去etcd注册中心注册服务，client端马上正常工作。        \n```\n\n# Spring配置\n服务提供者，使用自定义注解@Service来暴露服务，通过interfaceClass来指定服务的接口。        \n该@Service注解是iris提供的，并非Spring的注解\n```java\n@Service(interfaceClass = IHelloService.class)\npublic class HelloService implements IHelloService {\n    @Override\n    public String hello(String name) throws Exception {\n        return \"hello\" + name;\n    }\n}\n```\n服务使用者，通过@Reference来引用远程服务，就像使用本地的SpringBean一样。背后的SpringBean封装和Rpc调用对开发者透明。使用体验和Dubbo是一样的。\n```java\npublic class Baz {\n\n    @Reference(interfaceClass = IHelloService.class)\n    private IHelloService helloService;\n\n    public void hello(String name) throws Exception {\n        System.out.println(helloService.hello(name));\n    }\n}\n\n```\n配置服务提供者，本例子使用XML配置，使用Java Code配置也可以。\n```xml\n\u003cbean id=\"registry\" class=\"com.leibangzhu.iris.registry.EtcdRegistry\"\u003e\n        \u003cconstructor-arg name=\"registryAddress\" value=\"http://127.0.0.1:2379\"\u003e\u003c/constructor-arg\u003e\n    \u003c/bean\u003e\n\n    \u003cbean id=\"server\" class=\"com.leibangzhu.iris.server.RpcServer\"\u003e\n        \u003cconstructor-arg name=\"registry\" ref=\"registry\"\u003e\u003c/constructor-arg\u003e\n    \u003c/bean\u003e\n\n    \u003cbean id=\"serviceAnnotationBeanPostProcessor\" class=\"com.leibangzhu.iris.spring.ServiceAnnotationBeanPostProcessor\"\u003e\u003c/bean\u003e\n\n    \u003cbean id=\"helloService\" class=\"com.leibangzhu.iris.spring.HelloService\"\u003e\u003c/bean\u003e\n```\n配置服务消费者，本例子使用XML配置，使用Java Code配置也可以。\n```xml\n\u003cbean id=\"registry\" class=\"com.leibangzhu.iris.registry.EtcdRegistry\"\u003e\n        \u003cconstructor-arg name=\"registryAddress\" value=\"http://127.0.0.1:2379\"\u003e\u003c/constructor-arg\u003e\n    \u003c/bean\u003e\n\n    \u003cbean id=\"client\" class=\"com.leibangzhu.iris.client.RpcClient\"\u003e\n        \u003cconstructor-arg name=\"registry\" ref=\"registry\"\u003e\u003c/constructor-arg\u003e\n    \u003c/bean\u003e\n\n    \u003cbean id=\"referenceAnnotationBeanPostProcessor\" class=\"com.leibangzhu.iris.spring.ReferenceAnnotationBeanPostProcessor\"\u003e\u003c/bean\u003e\n\n    \u003cbean id=\"foo\" class=\"com.leibangzhu.iris.spring.Baz\"\u003e\u003c/bean\u003e\n```\n\n# Spring Boot配置\n使用原生的Spring配置还是有些繁琐，可以使用Spring Boot来获得更好的开发体验。        \n服务提供者\n```java\n@Service(interfaceClass = IHelloService.class)\npublic class HelloService implements IHelloService {\n    @Override\n    public String hello(String name) throws Exception {\n        return \"Hello, \" + name + \", from com.leibangzhu.iris.springboot.HelloService\";\n    }\n}\n```\n服务消费者\n```java\n@Component\npublic class Foo {\n\n    @Reference(interfaceClass = IHelloService.class)\n    private IHelloService helloService;\n\n    public String hello(String name) throws Exception {\n        return helloService.hello(name);\n    }\n}\n```\n在application.properties文件中配置服务提供者\n```properties\niris.registry.address=http://127.0.0.1:2379\n\niris.server.enable=true\niris.server.port=2017\niris.annotation.package=com.leibangzhu.iris.springboot\n```\n在application.properties文件中配置服务消费者\n```properties\niris.registry.address=http://127.0.0.1:2379\n\niris.client.enable=true\n```\n使用SpringBoot时，不许再手动配置相关的spring bean，Iris提供的spring boot starter会自动配置好这些spring bean。\n\n# Iris的微内核加插件机制\n* Iris使用了SPI机制，实现了微内核加插件的架构。\n* Iris里的许多功能都是以插件的形式加载的。一个功能点就是一个扩展点，就是一个接口。通过注入的方式，将某个实现注入到Iris中。        \n* 扩展点的加载没有使用第三方的容器，比如Spring，而是自己实现了一个轻量级的容器。对Java的SPI机制进行了一下扩展和加强。        \n* 每个扩展点会有多个实现，开发者可以自己配置使用哪个，比如使用zookeeper注册中心或etcd注册中心。\n* Iris内置的扩展实现满足大部分要求，开发者也可以自己编写扩展点的实现，加载到Iris中。\n* Iris会扫描classpath下面的`/META/extensions`文件夹中的文件，读取扩展点信息，然后运行时动态加载。\n* 使用时通过ExtensionLoader加载对应的插件\n* ExtensionLoader支持类似于Spring的IoC和AoP功能。即，扩展点中可以自动装配其他的扩展点。Iris提供Wrapper使用Decrator模式来实现AOP。\n* 所有的扩展点元数据文件都在`/META-INF/extensions`文件夹下，文件名是实现的扩展点的接口的全类名。\n* 文件的内容是key=value的形式。key是扩展点实现的name，value是实现类的全类名。实现类是一个简单的Java类，不依赖任何第三方接口和注解。\n* 使用Wrapper实现AOP时，在扩展点name前加上`+`。比如:`+logWrapper=com.leibangzhu.iris.core.SomeExtension`\n\n### 一个负载均衡器的Demo\nIris中的服务提供者有多个，client端调用的时候，有一个负载均衡的策略。\nIris目前提供了1个实现：随机选择一个提供者。以后会提供更多的负载均衡策略。如果有多个，只需要在iris.properties或application.properties中添加配置：\n```properties\niris.loadbalance=random\n```\nIris提供的的`ILoadBalance`接口。\n```java\n@Extension(defaultValue = \"random\")\npublic interface ILoadBalance {\n    int select(@Adaptive(\"loadbalance\")Map\u003cString,String\u003e config,int amount) throws Exception;\n}\n```\n* @Extension注解声明这是一个扩展点\n* defaultValue表示默认使用random这个扩展点实现\n* @Adaptive注解声明这是一个自适应扩展方法，会根据运行时信息动态选择对应的扩展点实现。类似于一个动态代理。\n自带的随机的负载均衡是在下面的文件中定义的：\n`/src/main/resources/META-INF/extensions/com.leibangzhu.iris.core.loadbalance.ILoadBalance`文件的内容:\n```text\nrandom=com.leibangzhu.iris.core.loadbalance.RandomLoadBalance\n```\n通过ExtensionLoader获取扩展点：\n```java\nILoadBalance loadBalance = ExtensionLoader.getExtensionLoader(ILoadBalance.class).getAdaptiveInstance();\n// get runtime configuration and load config to map\n// get actual loadbalance from iris.properties or application.properties file\nString loadbalance = IrisConfig.getLoadbalance();\nmap.put(\"loadbalance\",loadbalance)\nloadBalance.select(map,size);\n```\n\n### 扩展自己的负载均衡器\n开发者想使用轮询的负载均衡策略，可以按照以下步骤来扩展：\n1. 编写一个类，实现ILoadBalance接口\n```java\npublic class RoundRobinLoadBalance implements ILoadBalance {\n    @Override\n    public int select(Map\u003cString, String\u003e config, int amount) throws Exception {\n        // put your code here ...\n    }\n}\n```\n2. 在classpath中添加一个文件：\n`/META-INF/extensions/com.leibangzhu.iris.core.loadbalande.ILoadBalance`\n```properties\nroundrobin=com.mycompany.foo.bar.RoundRobinLoadBalance\n```\n3. 在`iris.properties`或`application.properties`中添加配置：\n```properties\niris.loadbalance=roundrobin\n```\n这样，Iris就会使用我们自定义的轮询负载均衡了。\n\n# Why iris\n`iris`取名于梵高的画**鸢尾花**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleiwei2094%2Firis-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleiwei2094%2Firis-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleiwei2094%2Firis-java/lists"}