引言
之前学习了dubbo,一直没有实战,今天动手了才发现,里面还是又一些坑要踩,在网上找了好多文章,挂羊头卖狗肉,搜不到有用的信息,然后自己花了一下午时间,一个个慢慢调配,在此留个记录,希望大家少走点弯路。
版本:
springboot-2.2.x dubbo-2.7.x
新建三个项目:
各位都是有经验的开发人员,新建项目我就不做赘述了。
父工程 pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
api
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.8.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.8.0.Final</version>
</dependency>
</dependencies>
public interface ITestService {
String say();
String fight(String name0, String name1);
}
@Path("/users") // 这些注解是rest协议的写法
public interface IUserService {
@POST
@Path("/register")
@Consumes({MediaType.APPLICATION_JSON,MediaType.TEXT_HTML}) //表示接收json、html格式 的数据
@Produces({MediaType.APPLICATION_JSON,MediaType.TEXT_HTML})//表示返回json、html格式 的数据
void registerUser(User user);
}
@Data
public class User implements Serializable {
private String id;
private String name;
}
以上定义了两个接口和一个实体类。
服务提供方provider
application.yml :
server:
port: 8000
spring:
cloud:
nacos:
discovery:
server-addr: 172.18.12.32:8848
dubbo:
# 定义两个协议 dubbo,rest(使用jetty作为服务器)
protocols:
dubbo:
name: dubbo
port: 20880
rest:
name: rest
port: 9999
server: jetty
# 定义两个注册中心 这里偷了个懒 都是使用nacos
registries:
nacos1:
registry:
address: nacos://172.18.12.32:8848
id: nacos1
# 必须要绑定协议
protocol: dubbo
nacos2:
registry:
address: nacos://172.18.12.32:8848
id: nacos2
protocol: rest
application:
# 服务提供方名称,必须要提供 否则会报错
name: dubbo-provider
registry:
address: nacos://172.18.12.32:8848
register: false # 表示不把自己注册上去,只注册服务
registry还可以这么配置
<!-- 多注册中心配置,竖号分隔表示同时连接多个不同注册中心,同一注册中心的多个集群地址用逗号分隔 -->
<dubbo:registry address="10.20.141.150:9090|10.20.154.177:9010" />
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.8.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.8.0.Final</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
@SpringBootApplication
@DubboComponentScan("com.example.demo.service")
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
@DubboService(protocol = {"dubbo"},interfaceClass = ITestService.class)
public class TestService implements ITestService {
@Override
public String say() {
return "hello";
}
@Override
public String fight(String name0, String name1) {
return name0 + "flight and " + name1 + "in time " + new Date();
}
}
@Path("/users")
@DubboService(interfaceClass = IUserService.class,protocol = {"rest","dubbo"},version = "1.0")
public class UserServiceImpl implements IUserService {
@POST
@Path("/register")
@Consumes({MediaType.APPLICATION_JSON,MediaType.TEXT_HTML})
@Produces({MediaType.APPLICATION_JSON,MediaType.TEXT_HTML})
public void registerUser(User user) {
// save the user...
System.out.println(111);
}
}
解释:
-
UserServiceImpl ,TestService 是api模块中两个接口的实现,其中TestService使用单协议dubbo,如果不配置默认就是dubbo协议,UserServiceImpl使用了两个协议 dubbo,rest协议。协议绑定了两个注册地址,这里都使用nacos。
-
最后记得在启动类上加注解@DubboComponentScan指定包,dubbo会根据配置扫描包并发布服务。
扫描二维码关注公众号,回复: 12481890 查看本文章
如图: UserServiceImpl配置了两种协议,发布了两个服务。如果注册中心有两个的话就会一边一个。
服务消费方
pom.xml
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
application.yml
server:
port: 8001
spring:
application:
name: consumer
cloud:
nacos:
discovery:
server-addr: 172.18.12.32:8848
dubbo:
registry:
address: nacos://172.18.12.32:8848
check: false # 启动不检查
register: false # 表示不把自己注册上去,只注册服务
application:
name: dubbo-consumer
protocols:
rest:
name: rest
port: 9999
server: jetty
dubbo:
name: dubbo
port: 20880
@RestController
@RequestMapping("/test")
public class TestController {
// 不做配置默认协议为dubbo,默认检查
@DubboReference
private ITestService testService;
// 配置check = false,启动时不会报错,指定协议为 rest,version为版本号,和服务提供方对应
@DubboReference(version = "1.0",check = false,protocol = "rest")
private IUserService userService;
@GetMapping("/aaa")
public String aaa() {
return testService.say();
}
@GetMapping("/flight")
public String flight(String name0, String name1) {
return testService.fight(name0, name1);
}
@GetMapping("/user")
public String user(User user) {
userService.registerUser(user);
System.out.println(user);
return "success";
}
}
rest协议 结果:
dubbo协议 结果: