胡金强的第 8 篇原创文章
前言
当下Java 生态环境里面,微服务占据了非常大的份额,现在大部分新开发的 Java选型的后台程序都很奇妙的会跟微服务发生一些关系。那目前市面上主流的微服务方向主要有 Spring 家族推出的Spring Boot Cloud 还有阿里巴巴推出的 Dubbo 服务。
这两种服务我都大体上的使用过,说一下我的感受。我感觉Spring Boot Cloud 周边的服务功能框架比较健全,如果希望快速的搭建起一个大型的商业类型的项目可以选择Spring Boot Cloud,毕竟人家血统纯正的 Spring Boot体系,以及最近挺火的 Spring Cloud Alibaba 感觉也挺不错的。Dubbo 服务这边大体就是使用 nacos 或者 zookeeper 作为注册中心来实现微服务,可能周边的服务框架没有 Spring BootCloud 那样健全,但是个人感觉 Dubbo 的服务调用会比 feign 和 ribbon 舒服一点。所以我就想粗略的讲一下 Dubbo 和 Nacos 怎么使用。
创建服务
创建一个 maven 项目,下面三个子项目,分别是 common,provider,consumer。
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0modelVersion> <groupId>com.learngroupId> <artifactId>springboot-dubbo-nacosartifactId> <version>1.0.0.LEARNversion> <packaging>pompackaging> <name>springboot-dubbo-nacosname> <url>http://maven.apache.orgurl> <properties> <project.build.sourceEncoding>UTF-8project.build.sourceEncoding> properties> <modules> <module>commonmodule> <module>consumermodule> <module>providermodule> modules> <dependencyManagement> <dependencies> <dependency> <groupId>com.learngroupId> <artifactId>commonartifactId> <version>${version}version> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> <version>2.3.5.RELEASEversion> <scope>testscope> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> <version>2.3.5.RELEASEversion> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starterartifactId> <version>2.3.5.RELEASEversion> dependency> <dependency> <groupId>org.apache.dubbogroupId> <artifactId>dubbo-spring-boot-starterartifactId> <version>2.7.8version> dependency> <dependency> <groupId>com.alibaba.nacosgroupId> <artifactId>nacos-clientartifactId> <version>1.4.0version> dependency> dependencies> dependencyManagement>project>
Common 模块
common 模块用作定义 provider 和 consumer 模块当中公共的类和接口,为了怎么代码的耦合度。如果不使用 common 模块,就必须在 provider 和 consumer 模块当中都定义调用接口和实体类。
pom.xml:
<?xml version="1.0"?><project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0modelVersion> <artifactId>commonartifactId> <name>commonname> <url>http://maven.apache.orgurl> <packaging>jarpackaging> <parent> <groupId>com.learngroupId> <artifactId>springboot-dubbo-nacosartifactId> <version>1.0.0.LEARNversion> parent> <properties> <project.build.sourceEncoding>UTF-8project.build.sourceEncoding> properties> <dependencies> dependencies>project>
定义服务调用接口:
package com.learn.common.handler.service;/** * 调用接口 * @author xiaohu * */public interface IHelloService { public String hello(); }
provider 模块
provider 作为服务的提供者,只需要实现 common 中定义的接口就行了,然后就是把服务通过 Dubbo 注册到注册中心。
pom.xml:
<?xml version="1.0"?><project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0modelVersion> <artifactId>providerartifactId> <name>providername> <url>http://maven.apache.orgurl> <packaging>jarpackaging> <parent> <groupId>com.learngroupId> <artifactId>springboot-dubbo-nacosartifactId> <version>1.0.0.LEARNversion> parent> <properties> <project.build.sourceEncoding>UTF-8project.build.sourceEncoding> properties> <dependencies> <dependency> <groupId>com.learngroupId> <artifactId>commonartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> <scope>testscope> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starterartifactId> dependency> <dependency> <groupId>org.apache.dubbogroupId> <artifactId>dubbo-spring-boot-starterartifactId> dependency> <dependency> <groupId>com.alibaba.nacosgroupId> <artifactId>nacos-clientartifactId> dependency> dependencies>project>
启动类:
package com.learn.provider;import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * 服务提供者启动类 * * @author xiaohu * */// 激活 Dubbo 服务@EnableDubbo@SpringBootApplicationpublic class ProviderApplication { public static void main(String[] args) { System.out.println("Provider Application Starter ..."); SpringApplication.run(ProviderApplication.class, args); System.out.println("Provider Application Starter Successful!"); }}
application.properties:
# 启动端口server.port=8000# dubbo + nacosdubbo.application.name=providerdubbo.registry.address=nacos://localhost:8848dubbo.protocol.port=20881dubbo.protocol.name=dubbo
接口实现:
package com.learn.provider.handler.service;import org.apache.dubbo.config.annotation.DubboService;import com.learn.common.handler.service.IHelloService;/** * IHelloService 实现类 * @author xiaohu * */@DubboServicepublic class HelloService implements IHelloService { public String hello() { // TODO Auto-generated method stub return "Hello World!"; } }
consumer 模块
consumer 作服务的消费者,调用服务接口。
pom.xml:
<?xml version="1.0"?><project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0modelVersion> <artifactId>consumerartifactId> <name>consumername> <url>http://maven.apache.orgurl> <packaging>jarpackaging> <parent> <groupId>com.learngroupId> <artifactId>springboot-dubbo-nacosartifactId> <version>1.0.0.LEARNversion> parent> <properties> <project.build.sourceEncoding>UTF-8project.build.sourceEncoding> properties> <dependencies> <dependency> <groupId>com.learngroupId> <artifactId>commonartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> <scope>testscope> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> dependency> <dependency> <groupId>org.apache.dubbogroupId> <artifactId>dubbo-spring-boot-starterartifactId> dependency> <dependency> <groupId>com.alibaba.nacosgroupId> <artifactId>nacos-clientartifactId> dependency> dependencies>project>
启动类:
package com.learn.consumer;import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * 服务消费者启动类 * * @author xiaohu * */// 激活 Dubbo@EnableDubbo@SpringBootApplicationpublic class ConsumerApplication { public static void main(String[] args) { System.out.println("Consumer Application Starter ..."); SpringApplication.run(ConsumerApplication.class, args); System.out.println("Consumer Application Starter Successful!"); }}
application.properties:
# 启动端口server.port=8001# dubbo + nacosdubbo.application.name=consumerdubbo.registry.address=nacos://localhost:8848dubbo.protocol.port=20881dubbo.protocol.name=dubbo
服务调用:
package com.learn.consumer.endpoint.controller;import org.apache.dubbo.config.annotation.DubboReference;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import com.learn.common.handler.service.IHelloService;/** * 服务调用 * @author xiaohu * */@RestControllerpublic class HelloController { @DubboReference private IHelloService helloService; @RequestMapping(value = "/hello", method = RequestMethod.GET) public String hello() { return helloService.hello(); } }
运行测试一下:
先启动 nacos 服务:
先启动 provider 和 consumer 服务:
两个服务都已经成功的起来了。可以访问 http://localhost:8001/hello 测试一下。
也是成功的,之后我们访问一下 nacos 的注册中心看一下,是否有两个服务注册在上面。
总结
到此,一个简单的通过 Dubbo 完成的服务调用就写完了。这里需要说明,common 模块并不是必须的,只是个人的编码习惯,为的实体类和接口可以复用而已。如果不喜欢的可以在调用和实现模块中定义就行了,但是必须保证接口内容能对上。
服务启动顺序最好是按照,服务提供者优先启动,服务消费者后面启动的原则。
现在来说 Dubbo 经过了一段时间的断维之后,又开始维护了。我觉得这个是一件好的事情,给我们提供了更多元化的一个选择。也希望这篇文章能够帮助到大家,谢谢。