https://blog.csdn.net/IT_Holmes/article/details/124518330
部署ZooKeeper
详情见ZooKeeper
搭建控制台管理
- 去Dubbo官方的Github上面下载dubbo-admin项目
git clone https://github.com/apache/dubbo-admin.git
修改application.properties配置
按官方的方法来一步步启动
Production Setup
- Clone source code on develop branch git clone
https://github.com/apache/dubbo-admin.git
- Specify registry address in
dubbo-admin-server/src/main/resources/application.properties
- Build
mvn clean package -Dmaven.test.skip=true
- 打包后可以在每个对应的target目录下,找到打包后的jar包
java -jar 包名
:就可以执行的。
- Start dubbo-admin
mvn --projects dubbo-admin-server spring-boot:run
ORcd dubbo-admin-distribution/target
;java -jar dubbo-admin-0.1.jar
- 注意要启动zookeeper注册中心。
- Visit
http://localhost:8080
- Default username and password is
root
dubbo-admin是管理页面应该属于Monitor监视部分,就算没有也不影响整个dubbo的工作:
- dubbo admin是dubbo的图形页面控制台,具有服务查询、服务治理的功能。
问题一:8080端口占用
zookeeper 的一些高版本中包含一个AdminServer默认的端口是8080,所以导致8080端口占用,dubbo的jar包没法启动。
解决:修改dubbo-admin-server目录下面的application.properties文件添加server.port=9980,将其端口号改为9980。对应访问页面就成http://localhost:9980/
了。
问题二: zookeeper not connected
https://zhuanlan.zhihu.com/p/343204228
进入发现,在CuratorZookeeperClient类中设置了连接的超时时间
int timeout = url.getParameter("timeout",
this.DEFAULT_CONNECTION_TIMEOUT_MS);
正确配置:
- 修改application.properties文件
问题三:zookeeper提示包太大
https://www.iteye.com/blog/shift-alt-ctrl-1845568
原因:
客户端发送的包太大,超过jute.maxbuffer的设置,默认大小为1048575。
解决
修改jute.maxbuffer的配置,设置成50M
- 修改zookeeper配置文件
搭建服务提供者、消费者
创建主module
创建 dubbo-demo 模块,在pom.xml引入需要的依赖
<properties>
<dubbo.version>3.0.8</dubbo.version>
</properties>
<dependencies>
<!-- JAX-RS API -->
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<!-- 引入Dubbo3 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
</dependency>
</dependencies>
搭建公共项目
其他服务添加相应的依赖
<dependency>
<groupId>com.huang</groupId>
<artifactId>dubbo-demo-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
XML方式
- 创建dubbo-demo-xml模块,引入上面的公共项目
- 服务提供者配置
- 在服务提供者项目上面创建配置文件,暴露服务 ```xml <?xml version=”1.0” encoding=”UTF-8”?>
2. 只需要导入xml文件,在spring中执行就可以了
```java
package com.huang.dubbo.demo.provider;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class XmlProviderApplication {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-provider.xml");
context.start();
System.in.read();
}
}
- 服务消费者配置
创建consumer.xml文件,配置dubbo对应文件。 ```xml <?xml version=”1.0” encoding=”UTF-8”?>
- 创建一个main方法来测试,是否能调用成功
```java
package com.huang.dubbo.demo.consumer;
import com.huang.dubbo.demo.DemoService;
import com.huang.dubbo.demo.GreetingService;
import com.huang.dubbo.demo.RestDemoService;
import com.huang.dubbo.demo.TripleService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.concurrent.*;
public class XmlConsumerApplication {
private static final int CORE_POOL_SIZE = 10;
private static final int MAX_POOL_SIZE = 100;
private static final int KEEP_ALIVE_TIME = 10;
private static final int QUEUE_CAPACITY = 200;
public static void main(String[] args) throws InterruptedException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml");
context.start();
DemoService demoService = context.getBean("demoService", DemoService.class);
GreetingService greetingService = context.getBean("greetingService", GreetingService.class);
RestDemoService restDemoService = context.getBean("restDemoService", RestDemoService.class);
TripleService tripleService = context.getBean("tripleService", TripleService.class);
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,MAX_POOL_SIZE,KEEP_ALIVE_TIME
,TimeUnit.SECONDS,new ArrayBlockingQueue<>(QUEUE_CAPACITY), Executors.defaultThreadFactory());
poolExecutor.execute(() -> {
while (true) {
try {
String greetings = greetingService.hello();
System.out.println(greetings + " from separated thread.");
} catch (Exception e) {
// e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
});
poolExecutor.execute(()->{
while (true) {
try {
String restResult = restDemoService.sayHello("rest");
System.out.println(restResult + " from separated thread.");
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
});
poolExecutor.execute(()->{
while (true) {
try {
String restResult = tripleService.hello();
System.out.println(restResult + " from separated thread.");
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
});
while (true) {
try {
CompletableFuture<String> hello = demoService.sayHelloAsync("world");
System.out.println("result: " + hello.get());
String greetings = greetingService.hello();
System.out.println("result: " + greetings);
} catch (Exception e) {
// e.printStackTrace();
}
Thread.sleep(5000);
}
}
}
- 控制台管理调用
注解方式
- 创建dubbo-demo-annotation模块,引入上面的公共项目
- 服务提供者配置
新增配置文件dubbo-provider.properties
dubbo.application.name=dubbo-demo-annotation-provider
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
创建一个main方法来测试,是否能调用成功 ```java package com.huang.dubbo.demo.provider;
import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource;
public class AnnotationProviderApplication {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class);
context.start();
System.in.read();
}
@Configuration
@EnableDubbo(scanBasePackages = "com.huang.dubbo.demo.provider")
@PropertySource("classpath:/spring/dubbo-provider.properties")
static class ProviderConfiguration {
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("zookeeper://127.0.0.1:2181");
return registryConfig;
}
}
}
- **服务消费者配置**
![image.png](https://cdn.nlark.com/yuque/0/2022/png/1416299/1654076914448-3720a922-0a70-45a2-aaa3-2cd61afc97ee.png#clientId=u9d41dfc5-c512-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=281&id=u3beaa577&margin=%5Bobject%20Object%5D&name=image.png&originHeight=281&originWidth=344&originalType=binary&ratio=1&rotation=0&showTitle=false&size=65165&status=done&style=none&taskId=u2c23e693-22d5-4d61-ae1f-79ebdf2ff4f&title=&width=344)
1. 新增配置文件dubbo-consumer.properties
```java
dubbo.application.name=dubbo-demo-annotation-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.port=-1
- 添加配置文件DemoServiceComponent ```java package com.huang.dubbo.demo.consumer.comp;
import org.apache.dubbo.config.annotation.DubboReference; import com.huang.dubbo.demo.DemoService; import org.springframework.stereotype.Component;
import java.util.concurrent.CompletableFuture;
@Component(“demoServiceComponent”) public class DemoServiceComponent implements DemoService { @DubboReference private DemoService demoService;
@Override
public String sayHello(String name) {
return demoService.sayHello(name);
}
@Override
public CompletableFuture<String> sayHelloAsync(String name) {
return null;
}
}
3. 创建一个main方法来测试,是否能调用成功
```java
package com.huang.dubbo.demo.consumer;
import com.huang.dubbo.demo.DemoService;
import com.huang.dubbo.demo.consumer.comp.DemoServiceComponent;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
public class AnnotationConsumerApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);
context.start();
DemoService service = context.getBean("demoServiceComponent", DemoServiceComponent.class);
String hello = service.sayHello("world");
System.out.println("result :" + hello);
}
@Configuration
@EnableDubbo(scanBasePackages = "com.huang.dubbo.demo.consumer.comp")
@PropertySource("classpath:/spring/dubbo-consumer.properties")
@ComponentScan(value = {"com.huang.dubbo.demo.consumer.comp"})
static class ConsumerConfiguration {
}
}
- 调用
SpringBoot方式
创建dubbo-demo-spring-boot模块,引入上面的公共项目,并引入springboot依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>${spring-boot.version}</version>
<exclusions>
<!-- Fix the bug of log4j refer:https://github.com/apache/logging-log4j2/pull/608 -->
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
服务提供者配置
dubbo:
application:
name: dubbo-demo-springboot-provider
protocol:
name: dubbo
port: -1
registry:
id: zk-registry
address: zookeeper://127.0.0.1:2181
config-center:
address: zookeeper://127.0.0.1:2181
metadata-report:
address: zookeeper://127.0.0.1:2181
server:
port: 6060
package com.huang.dubbo.demo.provider;
import com.huang.dubbo.demo.DemoService;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.rpc.RpcContext;
@DubboService
public class DemoServiceImpl implements DemoService {
@Override
public String sayHello(String name) {
System.out.println("Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
return "Hello " + name;
}
}
package com.huang.dubbo.demo.provider;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.concurrent.CountDownLatch;
@SpringBootApplication
@EnableDubbo(scanBasePackages = {"com.huang.dubbo.demo.provider"})
public class SpringBootProviderApplication {
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(SpringBootProviderApplication.class,args);
System.out.println("dubbo service started");
new CountDownLatch(1).await();
}
}
- 服务消费者配置
dubbo:
application:
name: dubbo-demo-springboot-consumer
protocol:
name: dubbo
port: -1
registry:
id: zk-registry
address: zookeeper://127.0.0.1:2181
config-center:
address: zookeeper://127.0.0.1:2181
metadata-report:
address: zookeeper://127.0.0.1:2181
server:
port: 6061
package com.huang.dubbo.demo.consumer;
import com.huang.dubbo.demo.DemoService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
@Service
public class SpringService {
@DubboReference
private DemoService demoService;
public String doSayHello(String name) {
return demoService.sayHello(name);
}
}
package com.huang.dubbo.demo.consumer;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
@EnableDubbo
public class SpringBootConsumerApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringBootConsumerApplication.class, args);
SpringService application = context.getBean(SpringService.class);
String result = application.doSayHello("world");
System.out.println("result: " + result);
}
}
- 调用