dubbo学习第一部分基础配置
什么是dubbo
我们知道,在分布式环境下,有多个微服务模块,微服务可能分布在不同的主机上,各个服务之间要进行通信,这就涉及到远程通信的问题,而dubbo就是解决微服务之间通信问题的框架,其rpc(远程过程调用)的通信机制使得在调用其他服务方法时就像调用本地方法一样,它是面向接口的,虽然也是分布式框架,但与springcloud不同的是,springcloud包含了微服务的各个组件,而dubbo可以认为只是微服务之间的一个通信组件,需要与其他组件结合使用才能构成一套完整的微服务解决方案。
dubbo与springcloud整合的三种方式
传统的xml方式整合
1.首先构建提供者
代码如下
package com.huang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author hcc
* @date 2020-10-16 9:35
* @description
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private String id;
private int age;
private String name;
}
package com.huang.service;
import com.huang.pojo.User;
import java.util.List;
/**
* @author hcc
* @date 2020-10-16 9:34
* @description
*/
public interface UserService {
public List<User> queryAllUser(String id) throws InterruptedException;
}
package com.huang.service;
import com.huang.pojo.User;
import java.util.*;
/**
* @author hcc
* @date 2020-10-16 9:34
* @description
*/
public class UserServiceImpl implements UserService{
User user0 = new User("1",2,"3");
User user1 = new User("a",2,"c");
List<User> list= new ArrayList<User>() {
{
this.add(user0);
this.add(user1);
}
};
public List<User> queryAllUser(String id) throws InterruptedException {
Thread.sleep(4000);
System.out.println("老版本用户id为"+id);
System.out.println("调用远程服务开始.....");
return list;
}
}
package com.huang;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
/**
* @author hcc
* @date 2020-10-16 10:49
* @description
*/
@SpringBootApplication
@ImportResource(locations={"classpath:provider.xml"})
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class,args);
}
}
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!--配置应用名-->
<dubbo:application name="userService-provider"/>
<!--配置注册中心-->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!--配置服务协议-->
<dubbo:protocol name="dubbo" port="20880"/>
<!--提供者里面也可以和消费者一样在对应位置配置超时时间,其优先级和消费者规则的一样,
如果消费者和提供者同时配置了但是级别一样,那么消费者将会优先,级别不一样则按照优先级高的那一方生效
即两个大原则:
1.精确优先(方法,接口,全局)
2.消费者设置优先(级别相同)
-->
<!--暴露服务,指向真正的实现对象,老版本-->
<dubbo:service interface="com.huang.service.UserService" ref="userServiceImpl" version="1.0.0"></dubbo:service>
<!--真正的服务实现对象-->
<bean class="com.huang.service.UserServiceImpl" id="userServiceImpl"></bean>
<!--暴露服务,指向真正的实现对象,新版本-->
<dubbo:service interface="com.huang.service.UserService" ref="userServiceImpl2" version="2.0.0"></dubbo:service>
<!--真正的服务实现对象-->
<bean class="com.huang.service.UserServiceImpl2" id="userServiceImpl2"></bean>
<!--配置所有提供者的统一规则-->
<dubbo:provider></dubbo:provider>
<!--配置监视器-->
<dubbo:monitor protocol="registry"></dubbo:monitor>
<!-- <dubbo:monitor address="127.0.0.1:7070"></dubbo:monitor>-->
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>dubbo</artifactId>
<groupId>com.test.huang</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-provider-9001</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<!-- dubbo-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<!-- zookeeper客户端-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.8.0</version>
</dependency>
<!-- <dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.8.0</version>
</dependency>-->
</dependencies>
</project>
1.再构建消费者
代码如下
package com.huang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author hcc
* @date 2020-10-16 9:35
* @description
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private String id;
private int age;
private String name;
}
package com.huang.service;
/**
* @author hcc
* @date 2020-10-16 12:07
* @description
*/
public interface OrderService {
public void getUser(String id);
}
package com.huang.service;
import com.huang.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author hcc
* @date 2020-10-16 12:08
* @description
*/
@Service
public class OrderServiceImpl implements OrderService {
//注入的时xml里面配置的提供者的service
@Autowired
UserService userService;
public void getUser(String id) {
List<User> list = userService.queryAllUser(id);
System.out.println("调用远程服务结束.....");
for (User user : list) {
System.out.println(user.toString());
}
}
}
package com.huang.service;
import com.huang.pojo.User;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author hcc
* @date 2020-10-16 9:34
* @description
*/
@Component
public interface UserService {
public List<User> queryAllUser(String id);
}
package com.huang;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
/**
* @author hcc
* @date 2020-10-16 10:49
* @description
*/
@SpringBootApplication
@ImportResource(locations={"classpath:consumer.xml"})
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class,args);
}
}
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.huang.service"></context:component-scan>
<!--配置应用名-->
<dubbo:application name="userService-consumer"/>
<!--配置注册中心-->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!--timeout表示在指定时间内还没返回结果则抛出异常-->
<!--引用提供者暴露的service-->
<!--timeout优先级第二-->
<!-- retries表示重试次数,不包含第一次调用
-一份服务有多个提供者时,重试次数是多个提供者被调用次数之和
-多次结果不变的操作(幂等)可以设置retries,非幂等操作不行
-->
<!-- version指定使用提供者哪个版本,*表示随机使用哪个版本-->
<dubbo:reference interface="com.huang.service.UserService" id="userService"
timeout="5000" retries="3" version="2.0.0" stub="com.huang.service.UserServiceStub">
<!--timeout优先级第一-->
<!--<dubbo:method name="queryAllUser" timeout="3000" ></dubbo:method>-->
</dubbo:reference>
<!--配置所有消费者的统一规则,不检查所有提供者服务是否注册-->
<!--timeout优先级第三-->
<dubbo:consumer check="false" timeout="2000"></dubbo:consumer>
<dubbo:monitor protocol="registry"></dubbo:monitor>
<!-- <dubbo:monitor address="127.0.0.1:7070"></dubbo:monitor>-->
</beans>
3.消费者编写main方法测试
java
package com.huang;
import com.huang.service.OrderService;
import com.huang.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.annotation.Order;
import java.io.IOException;
/**
* @author hcc
* @date 2020-10-16 11:08
* @description
*/
public class ConsumerMain {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("consumer.xml");
OrderService orderService = applicationContext.getBean(OrderService.class);
UserService userService = (UserService) applicationContext.getBean("userService");
orderService.getUser("aaa");
System.in.read();
}
}
使用yml或者.properties文件整合
在yml或者.properties(application.properties或者dubbo.properties)文件设置对应属性就可以代替xml文件,同时开启相关注解即可。
使用java配置类整合
package com.huang.config;
import com.alibaba.dubbo.config.*;
import com.huang.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* @author hcc
* @date 2020-10-16 17:49
* @description
*/
@Configuration
public class ProviderConfig {
// <dubbo:application name="userService-provider"/>
@Bean
public ApplicationConfig applicationConfig(){
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("userService-config");
return applicationConfig;
}
// <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
@Bean
public RegistryConfig registryConfig(){
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setProtocol("zookeeper");
registryConfig.setAddress("127.0.0.1:2181");
return registryConfig;
}
// <dubbo:protocol name="dubbo" port="20880"/>
@Bean
public ProtocolConfig protocolConfig(){
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setName("dubbo");
protocolConfig.setPort(20889);
return protocolConfig;
}
//<dubbo:service interface="com.huang.service.UserService" ref="userServiceImpl" version="1.0.0"></dubbo:service>
@Bean
public ServiceConfig serviceConfig(UserService userService){
ServiceConfig serviceConfig = new ServiceConfig();
serviceConfig.setInterface(UserService.class);
serviceConfig.setRef(userService);
serviceConfig.setVersion("1.0.0");
MethodConfig methodConfig = new MethodConfig();
methodConfig.setName("queryAllUser");
methodConfig.setTimeout(1000);
List<MethodConfig> methods = new ArrayList<>();
methods.add(methodConfig);
serviceConfig.setMethods(methods);
return serviceConfig;
}
//ProviderConfig
//MonitorConfig
}
注意:如果同时存在配置文件和配置类,则会创建多个服务,但必须要保证他们的应用名一样,否则会报错。
dubbo中的监控和管理
dubbo作为一个微服务调用框架,对于服务必然需要管理,而dubbo-admin就提供这样的管理机制,dubbo-monitor作为服务之间接口调用的管理平台。
dubbo服务管理
1.首先下载dubbo-admin源码,在打成jar包
2.运行启动访问,可以管理对应的服务
dubbo监控管理