springboot+zookeeper+dubbo的简单实现

1.前言


本篇文章旨在记录一下最近自己学习dubbo简单demo的过程。自己在学习过程中犯下很多低级的错误,在这里也记录下来借以警戒自己。

本文中zookeeper安装在vmware虚拟机上,系统为centos7,项目开发工具idea,使用maven管理jar包,使用git拉取dubbo-admin

另外此文章使用的dubbo为较早版本,因为自己之后想接触springcloud方面,所以此文章仅仅作了解dubbo用,理解万岁.

2.安装zookeeper


zookeeper在linux下的配置参考文章

1.下载zookeeper:在linux虚拟机上可以直接去zookeeper官网下载https://zookeeper.apache.org/
2.解压:tar -zxvf 下载的zookeeper
3.进入conf目录:cd 进入我们解压的文件下的conf目录 使用ls 我们能看到zoo_sample.cfg
4.复制一份配置文件:cp zoo_sample.cfg zoo.cfg 
5.ifconfig :先获取我们linux虚拟机的IP地址
6.开始编辑配置文件:vi zoo.cfg
7.修改两处即可:修改:i 退出esc :wq
              dataDir=/usr/zookeeper   
              server.1=192.168.147.128(这里需要替换成我们的ip地址):3888 
8.设置环境变量 export ZOOKEEPER_INSTALL=我们的路径/zookeeper-3.3.6  
             export PATH=$PATH:$ZOOKEEPER_INSTALL/bin 
9.启动  [root@localhost bin]# ./zkServer.sh start(在我们的zookeeper项目的bin下面运行)
10.测试 [root@localhost bin]# ./zkServer.sh status
             得出结果:Mode: standalone   单机模式
11.关闭防火墙:如果我们外部连接可能需要关闭防火墙或者开放接口 systemctl stop firewalld

3.安装dubbo-admin


dubbo-admin官方github网址

1.拉取:git clone https://github.com/apache/incubator-dubbo-admin.git
2.修改:dubbo-admin-server/src/main/resources/application-production.properties
       将下面三个地址改为我们虚拟机的地址就好了
       admin.registry.address=zookeeper://
       admin.config-center=zookeeper://
       admin.metadata-report.address=zookeeper://
3.打包,导入依赖:mvn clean package(需要很久,不要着急关闭窗口,一直等success的出现)
4.运行:mvn --projects dubbo-admin-server spring-boot:run
5.访问:http://localhost:8080

4.编写dubbo-demo


dubbo分布式服务参考文章

在下面的demo中,我们模拟一次数据查询,我们在消费者模块传入用户id和name,调用生产者的find方法,查询到用户的name和emai并返回,并传到前端页面展示出来,实现两个服务之间的信息交互

1.创建项目
  • 创建dubbo-demo项目
  • 创建dubbo-api模块
  • 创建dubbo-producer模块
  • 创建dubbo-consumer模块+Thymeleaf模板

对idea创建多模块如果不太了解:可以点这里

2.dubbo-api模块

dubbo-api的主要作用是创建公共接口,我们构造实体类(需要实现序列化),构造接口

1.创建实体类:User和Info
public class User implements Serializable {   //实体类需要实现序列化
    String id;
    String name;
    //getter and setter
}

public class Info implements Serializable {
    String name;
    String email;
    //getter and setter
}
2.创建接口UserService
import dubbo_api.entity.Info;
import dubbo_api.entity.User;

public interface UserService  {
     Info find(User user);
}
3.dubbo-producer
1.导入依赖

需要导入的依赖:demo_api模块,spring-boot-starter-dubbo,zookeeper,这三个模块在dubbo_producer和dubbo_consumer模块中都需要导入

        <dependency>
            <groupId>dubbo_demo</groupId>
            <artifactId>demo_api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>io.dubbo.springboot</groupId>
            <artifactId>spring-boot-starter-dubbo</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
        </dependency>
      .....可根据模块内容自主添加

当然我们也可以把spring-boot-starter-dubbo,zookeeper放在这两个的公共模块里导入

2.修改配置文件
#防止与dubbo-admin冲突
server.port=8083
#dubbo配置
spring.dubbo.application.name=producer
spring.dubbo.registry.address=zookeeper://:2181  #我们的zookeper地址
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.port=20880
spring.dubbo.scan=dubbo_producer.service         #这里填service接口实现的路径 包名+层名即可
#属性
[email protected]
user.id=1001
3.实现service接口
package dubbo_producer.service;

import com.alibaba.dubbo.config.annotation.Service;
import dubbo_api.entity.Info;
import dubbo_api.entity.User;
import dubbo_api.service.UserService;
import org.springframework.beans.factory.annotation.Value;

@Service                                        //dubbo自己的Service注解,而不是spring的
public class UserServiceImpl implements UserService {
    @Value("${user.email}")   private String email;  //获取配置文件值
    @Value("${user.id}")        private String id;     //获取配置文件值
    Info info =new Info();
    @Override
    public Info find(User user) {
        if(user.getId().equals(id)){
            System.out.println("查找到此人邮件");
            info.setName(user.getName());
            info.setEmail(email);
            return info;
        }else{
            System.out.println("查找不到此人邮件");
            info.setName(user.getName());
            info.setEmail("不详");
            return info;
        }
    }
}

4.dubbo-consumer
1.导入依赖(同生产者)
2.配置文件
## 避免和 server 工程端口冲突
server.port=8084
## Dubbo 服务消费者配置
spring.dubbo.application.name=consumer
spring.dubbo.registry.address=zookeeper://:2181      #zookeeper的地址
spring.dubbo.scan=dubbo_consumer.service             #我们的消费者调用接口下的路径 包名+层名
3.调用生产者
package dubbo_consumer.service;

import com.alibaba.dubbo.config.annotation.Reference;
import dubbo_api.entity.Info;
import dubbo_api.entity.User;
import dubbo_api.service.UserService;
import org.springframework.stereotype.Service;

@Service                                //spring的Service注解
public class HelloService  {
    @Reference                          //这里是dubbo的注解
    UserService userService;
    public Info login(){
        User user=new User();
        user.setId("1001");
        user.setName("张三");
        return userService.find(user);
    }
}
4.Controller层
package dubbo_consumer.controller;

import dubbo_consumer.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HelloController {
    @Autowired
    HelloService helloService;

    @RequestMapping("hello")
    public ModelAndView hello(){
        ModelAndView mv=new ModelAndView("hello");
        helloService.login();
        mv.addObject("userName",helloService.login().getName());
        mv.addObject("userEmail",helloService.login().getEmail());
        return mv;
    }
}
5.hello.html

<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>欢迎页面title>
head>
<body>

<div class="panel-body">
    welcome:<span th:text="${userName}">span>
div>
<div class="panel-body">
   your Email:<span th:text="${userEmail}">span>
div>
body>
html>
5.运行成功

运行成功html
springboot+zookeeper+dubbo的简单实现_第1张图片
springboot+zookeeper+dubbo的简单实现_第2张图片
springboot+zookeeper+dubbo的简单实现_第3张图片

6.经验总结

本次demo的实现虽然简单,但着实让我头疼了好一阵,浪费了好几个晚上的时间,现在程序运行起来,才发现错误都是因为自己作为菜鸟导致的一些低级错误,现在记录一下,引以为戒.

  • zookeeper篇
    1. zookeeper地址填写错误:因为自己刚看参考文章时不懂,完全copy,直到看网上需要ping通zookeeper端口号的时候,才后知后觉想到ping的是自己的虚拟机地址.
    2. linux防火墙开启: 这个问题并没有困扰自己多久,但是以后需要留意,任意一个虚拟机上的程序外部访问时都应该留意是否应该开启端口号或关闭防火墙.
    3. linux的网络没开:我们安装zookeeper的时候肯定会连接网络.但下一次开启虚拟机的时候,我们可能会忘记这一点.与此相似的错误还有网络地址发生变化,比如说外部笔记本连接不同的wifi.这是需要我们修改zookeeper的地址和demo中的配置文件.
  • dubbo-admin篇
    1. dubbo-admin执行mvn clean package指令的时候,慢,非常慢,起码10分钟以上,直接导致我认为git程序崩溃,或者某些下载文件被墙等情况,事实上,多等一会,就能看到胜利的曙光.
  • dubbo-demo篇
    1. @Reference无法取值的问题,在下方的日志里,如果看到程序根本就没有连接zookeeper的过程很有可能和我犯的是相同的错:配置文件中扫描的包就是消费者下用到@Reference对应的包.由于开头的参考文章中api,producer和consumer都用到的是相同的包名+路径名,我理解错误,导致这个可笑的错误
    2. 如果你想不写Service层,在消费者的Controller层调用生产者的话:我不知道会不会出错,因为我没有这么做,但如果出错的话,可以参考这里的文章,希望能解决你的问题
    3. 当然,你还可能出现一些马虎:生产者的@Service是dubbo的注解,消费者的@Service是spring的注解,而@reference是dubbo的注解,生产者应该先于消费者启动…

你可能感兴趣的:(微服务初学)