IDEA基于springboot采用Dubbo+zookeeper+Redis搭建微服务项目-详细教程

IDEA基于springboot采用Dubbo+zookeeper+Redis搭建微服务项目-详细教程

目录

前言

1.构建项目

2.提供者:Provider

2.1搭建基础设施,启动基本springboot项目

2.2Provide整合Dubbo

3.消费者:consumer

3.1搭建基础设施,引入提供方

3.2consumer配置Dubbo

4.使用zookeeper作为服务注册中心

 5.项目集成Redis

5.1引入方式

5.2新建common模块

 5.3配置Redis

6.结语


前言

自行下载dubbo,zookeeper,Redis,并进行基本配置,需要使用postman接口测试工具,redis客户端

1.构建项目

首先创建一个空的项目:

命名MicroServiceDemo,finish。

 new window

 创建两个模块提供者(provider)与消费者(consumer),在这里每个模块都采用SpringBoot项目,但是不引入任何其他组件。

 重复上面步骤再创建consumer模块

项目结构如下

2.提供者:Provider

2.1搭建基础设施,启动基本springboot项目

先编写基本的service和service的实现类serviImpl

package com.example.provider.service;

public interface ProviderService {

    String sayHello2Consumer(String s);

}
package com.example.provider.serviceImpl;

import com.example.provider.service.ProviderService;
import org.springframework.stereotype.Service;

@Service
public class ProvideServiceImpl implements ProviderService {

    @Override
    public String sayHello2Consumer(String s) {
        System.out.println("provider s : " + s);
        return s;
    }

}
package com.example.provider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }

}

此时启动项目,发现一运行就自动停止,也不报错

 因为项目创建的时候没有引入任何jar,所以此时项目缺少SpringBoot-web启动配置在pom文件下添加配置,重启启动,运行正常

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2.2Provide整合Dubbo

Dubbo有多种配置方式,在这只提两种:一种是注解,一种是xml文件配置

注解方式:在实现serviceImpl类上加的Service注解为Dubbo的注解,不能使用SpringBoot中的注解,并要设置服务名称;然后在消费端引入使用Interface注解,注明服务来源和服务名称,此外也需要在SpringBoot的配置文件中进行配置

参考网址:https://www.cnblogs.com/stars-one/p/12534295.html

XML文件方式:在资源包下新建xml文件,配置Dubbo的相关信息和服务,在消费端配置差异不大

参考网址:https://segmentfault.com/a/1190000019896723

在这推荐使用XML文件方式整合Dubbo,一是方便、快捷,不用多出配置;二是便于管理服务信息,查找修改都在一个文件。

而且大型项目一般都采用XML文件的方式,因此也比较实用,这里就只采用XML文件这种方式进行整合了。

1、首先在pom中引入相关配置

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.10</version>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.5</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.32.Final</version>
        </dependency>
        <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>

2、在resource目录下新建provider.xml的Dubbo配置文件

在这里先使用自动分配方式,不使用zookeeper作为消息注册中心。注意beans配置中引入dubbo。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans        
       http://www.springframework.org/schema/beans/spring-beans.xsd        
       http://code.alibabatech.com/schema/dubbo        
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->
    <dubbo:application name="provider" owner="ms"/>

    <dubbo:monitor protocol="registry"/>

    <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
    <dubbo:registry address="N/A" />

    <!--当前服务发布所依赖的协议;webserovice、Thrift、Hessain、http-->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!--服务发布的配置,需要暴露的服务接口-->
    <dubbo:service
            interface="com.example.provider.service.ProviderService"
            ref="providerService"/>

    <!--Bean bean定义-->
    <bean id="providerService" class="com.example.provider.serviceImpl.ProvideServiceImpl"/>

</beans>

关于配置文件里的信息,我引入我参考博客(这个博客也讲的非常详细)的介绍,供大家参考:

① 上面的文件其实就是类似 spring 的配置文件,而且,dubbo 底层就是 spring。
② 节点:dubbo:application
就是整个项目在分布式架构中的唯一名称,可以在 name 属性中配置,另外还可以配置 owner 字段,表示属于谁。
③ 节点:dubbo:monitor
监控中心配置, 用于配置连接监控中心相关信息,可以不配置,不是必须的参数。
④ 节点:dubbo:registry
配置注册中心的信息,比如,这里我们可以配置 zookeeper 作为我们的注册中心。address 是注册中心的地址,这里我们配置的是 N/A 表示由 dubbo 自动分配地址。或者说是一种直连的方式,不通过注册中心。
⑤ 节点:dubbo:protocol
服务发布的时候 dubbo 依赖什么协议,可以配置 dubbo、webserovice、Thrift、Hessain、http等协议。
⑥ 节点:dubbo:service
这个节点就是我们的重点了,当我们服务发布的时候,我们就是通过这个配置将我们的服务发布出去的。interface 是接口的包路径,ref 是第 ⑦ 点配置的接口的 bean。
⑦ 最后,我们需要像配置 spring 的接口一样,配置接口的 bean。

在启动类加上注解,SpringBoot在启动时,自动加载路径下的配置文件,整合Dubbo

@ImportResource(value = "provider.xml")

3、日志jar包冲突解决

此时启动项目报错,不要慌,兵来将挡,水来土掩,是log4j的jar包冲突

 用IDEA自带的工具去解决

 显示不全的点一下1:1试试,正常展示是这样,可以看出zkClient与zookeeper中的log4j冲突

 右键,将其排除,再次启动发现还有冲突为slf4j与logback的jar冲突,再用此方法排除掉slf4j的jar包就能正常运行了。

(SpringBoot支持log4j和logback日志,据说logback的性能要比log4j的性能好很多)

4、 最终pom文件为:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>provider</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.10</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>log4j</artifactId>
                    <groupId>log4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.5</version>
            <exclusions>
                <exclusion>
                    <artifactId>log4j</artifactId>
                    <groupId>log4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.32.Final</version>
        </dependency>
        <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>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

5、运行结果:

服务已经暴露出去了:注意日志中的host,应该就是你本机的IP,在配置consumer的时候要用到

[DUBBO] Export dubbo service com.example.provider.service.ProviderService to local registry, dubbo version: 2.6.6, current host: 169.254.125.184
[DUBBO] Export dubbo service com.example.provider.service.ProviderService to url dubbo://169.254.125.184:20880/com.example.provider.service.ProviderService?anyhost=true&application=provider&bean.name=com.example.provider.service.ProviderService&bind.ip=169.254.125.184&bind.port=20880&dubbo=2.0.2&generic=false&interface=com.example.provider.service.ProviderService&methods=sayHello2Consumer&owner=micro&pid=3016&side=provider&timestamp=1599669309167, dubbo version: 2.6.6, current host: 169.254.125.184

 引入参考博客对上面信息的解读

① 首先,在形式上我们发现,其实这么牛逼的 dubbo 也是用类似于 http 的协议发布自己的服务的,只是这里我们用的是 dubbo 协议
② dubbo://169.254.125.184:20880/com.example.provider.service.ProviderService
上面这段链接就是 ? 之前的链接,构成:协议://ip:端口/接口。发现是不是也没有什么神秘的。
③ anyhost=true&application=provider&bean.name=com.example.provider.service.ProviderService&bind.ip=169.254.125.184&bind.port=20880&dubbo=2.0.2&generic=false&interface=com.example.provider.service.ProviderService&methods=sayHello2Consumer&owner=micro&pid=3016&side=provider&timestamp=1599669309167, dubbo version: 2.6.6, current host: 169.254.125.184

?之后的字符串,分析后你发现,这些都是刚刚在 provider.xml 中配置的字段,然后通过 & 拼接而成的。

3.消费者:consumer

3.1搭建基础设施,引入提供方

先在pom文件中引入provider包,和web启动项,才可以进行基本代码编写,不然会找不到provider的service

        <dependency>
            <groupId>com.example</groupId>
            <artifactId>provider</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

package com.example.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

}
package com.example.consumer.controller;

import com.example.provider.service.ProviderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConsumerController {

    @Autowired
    private ProviderService providerService;

    @GetMapping("/hello")
    public void sayHello(){
        String str = providerService.sayHello2Consumer("Not hello, just hi. ");
        System.out.println("consumer get str = " + str + " from provide");
    }

}

此时项目是无法启动的,因为虽然引入了provider工程的包,但是consumer是找不到服务的,需要进行Dubbo配置来获取服务

3.2consumer配置Dubbo

1、在resource目录下创建consumer.xml文件,创建方法同provider.xml,配置内容如下

同样这里也不使用zookeeper作为服务注册中心,仅仅使用自动配置方式

注意dubbo:reference下url的IP是你的本机IP或者provider暴露服务的IP

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans        
       http://www.springframework.org/schema/beans/spring-beans.xsd        
       http://code.alibabatech.com/schema/dubbo        
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->
    <dubbo:application name="consumer" owner="ms"/>

    <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
    <!--点对点的方式-->
    <dubbo:registry address="N/A" />
    <!--<dubbo:registry address="zookeeper://localhost:2181" check="false"/>-->

    <!--生成一个远程服务的调用代理-->
    <!--点对点方式-->
    <dubbo:reference id="providerService"
                     interface="com.example.provider.service.ProviderService"
                     url="dubbo://169.254.125.184:20880/com.example.provider.service.ProviderService"/>

    <!--<dubbo:reference id="providerService"
                     interface="com.example.provider.service.ProviderService"/>-->

</beans>

2、在application.properties文件中修改Tomcat的启动默认端口号,因为Provide启动已经占用8080断开,再启动consumer默认也是8080端口,会冲突。

server.port=8081

 3、在consumer的启动类上加注解,consumer启动时自动加载注解下的配置文件,整合Dubbo

@ImportResource("consumer.xml")

 4、先启动Provider项目,再启动consumer项目,顺序错误会导致consumer找不到服务

[DUBBO] Successed connect to server /169.254.125.184:20880 from NettyClient 169.254.125.184 using dubbo version 2.6.6, channel is NettyChannel [channel=[id: 0x84bd591a, L:/169.254.125.184:3060 - R:/169.254.125.184:20880]], dubbo version: 2.6.6, current host: 169.254.125.184
[DUBBO] Start NettyClient DESKTOP-M67EI2N/169.254.125.184 connect to the server /169.254.125.184:20880, dubbo version: 2.6.6, current host: 169.254.125.184
[DUBBO] Refer dubbo service com.example.provider.service.ProviderService from url dubbo://169.254.125.184:20880/com.example.provider.service.ProviderService?application=consumer&dubbo=2.0.2&interface=com.example.provider.service.ProviderService&methods=sayHello2Consumer&owner=ms&pid=6548&register.ip=169.254.125.184&side=consumer&timestamp=1599745531530, dubbo version: 2.6.6, current host: 169.254.125.184

 5、用postman调一下接口,看控制台的输出情况,http://localhost:8081/hello(注意使用consumer的端口)

 provider提供方

consumer消费方

4.使用zookeeper作为服务注册中心

1、配置引入:实际上zookeeper配置已经在引入dubbo的时候引入过,需要做的只是配置。

provider.xml:设置服务注册中心为zookeeper

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->
    <dubbo:application name="provider" owner="ms"/>

    <dubbo:monitor protocol="registry"/>

    <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
<!--    <dubbo:registry address="N/A" />-->
    <dubbo:registry address="zookeeper://localhost:2181"/>

    <!--当前服务发布所依赖的协议;webserovice、Thrift、Hessain、http-->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!--服务发布的配置,需要暴露的服务接口-->
    <dubbo:service
            interface="com.example.provider.service.ProviderService"
            ref="providerService"/>

    <!--Bean bean定义-->
    <bean id="providerService" class="com.example.provider.serviceImpl.ProvideServiceImpl"/>

</beans>

consumer.xml:设置服务注册中心为zookeeper,这里不需要dubbo服务端提供的url了,直接引用就行了

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->
    <dubbo:application name="consumer" owner="ms"/>

    <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
    <!--点对点的方式-->
<!--    <dubbo:registry address="N/A" />-->
    <dubbo:registry address="zookeeper://localhost:2181" check="false"/>

    <!--生成一个远程服务的调用代理-->
    <!--点对点方式-->
<!--    <dubbo:reference id="providerService"-->
<!--                     interface="com.example.provider.service.ProviderService"-->
<!--                     url="dubbo://169.254.125.184:20880/com.example.provider.service.ProviderService"/>-->

    <dubbo:reference id="providerService"
                     interface="com.example.provider.service.ProviderService"/>

</beans>

 2、启动zookeeper后,再依次重启provider和consumer

 provider,信息比较多,截图也截不完

 consumer,可能会报一个端口占用的WARN,但是不影响大局,端口占用解决方法可以参考这个博主的博客

我这里采用在xml文件配置的方式在consumer.xml中修改dubbo配置

    <dubbo:application name="consumer" owner="ms">
        <dubbo:parameter key="qos.enable" value="true"/>
        <dubbo:parameter key="qos.accept.foreign.ip" value="false"/>
        <dubbo:parameter key="qos.port" value="33333"/>
    </dubbo:application>

 3、用postman工具验证,再调一次接口,看控制台输出情况

 5.项目集成Redis

5.1引入方式

心细的同学会发现,只有provider引入了先关的配置,而consumer只是引入了provider包,就也可以正常运行。实际上SpringBoot在引入provider模块的时候也引入了对应的配置,因此consumer就不用再做多余的配置了。

由此观之:如果我们provider和consumer都用到的东西,都放在一个公共的common模块下,然后让provider和consumer引入该模块,岂不是非常省事?

在此,新建模块common,这个模块不需要启动,因此只建成maven项目就可以,用来存放redis的配置.

当然你也不是非要创建一个模块不可,你也可以把它放在provider或者consumer中来使用。

(在我们实战项目中,common是必不可少的一个模块,里面可以存放各种工具类,DateUtil、StringUtil、MapUtil等等,也可以存放不常修改的类,比如常量类Constant,枚举类Enum等等)

话不多少,Let's do it !

5.2新建common模块

 groupid命名与consumer,provider一致

 

 5.3配置Redis

1、pom.xml文件引入redis配置,以及key与value序列化的依赖

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>common</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.8.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.10.3</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.3</version>
        </dependency>

    </dependencies>

</project>

2、编写RedisConfig配置类,主要是修改其默认的序列化方式,默认序列化方式为JdkSerializationRedisSerializer,编码格式为ISO-8859-1,值在传递过程中会出现乱码,将其修改为StringRedisSerializer,其编码方式为UTF-8,可解决乱码问题。

(我在这里写的比较简单,在实际项目中存储key,value的时候,可能存储对象的场景较多,序列化方式也会有所改变)

package com.example.common.redisCfg;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration
public class RedisConfig {
    
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 设置value的序列化规则和 key的序列化规则
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

3、编写RedisClient工具类,在这里我也就只写两个简单的设置key与value和通过key获取value的方法,在实际项目中需要许许多多,大家可以根据自己需求自行编写。

package com.example.common.redisCfg;

import com.example.common.constants.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedisClient {

   @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 设置指定 key 的值
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time == Constants.CACHE_EXP_FOREVER) {
                redisTemplate.opsForValue().set(key, value);
            } else {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取指定 key 的值
     *
     * @param key 键
     * @return 值
     */
    @SuppressWarnings("unchecked")
    public <T> T get(String key) {
        return key == null ? null : (T) redisTemplate.opsForValue().get(key);
    }
}

4、一个常量类

package com.example.common.constants;

public class Constants {

    //缓存时效-10秒
    public static int CACHE_EXP_TEN_SECONDS = 10;

    //缓存时效-1分钟
    public static int CACHE_EXP_MINUTE = 60;

    //缓存时效-永久有效
    public static int CACHE_EXP_FOREVER = 0;
}

5、在resource文件下application.properties(如果没有,自行创建)添加redis配置

# 数据库索引(默认为0)
spring.redis.database = 1
# 服务器地址
spring.redis.host = 127.0.0.1
# 服务器连接端口
spring.redis.port = 6379
# 服务器连接密码(默认为空)
spring.redis.password =
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait = -1
# 连接超时时间(毫秒)
spring.redis.timeout = 2000
# 连接池最大连接数
spring.redis.jedis.pool.max-active = 4
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle = 4
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle = 1

6、分别在provider和consumer的pom文件中添加common模块作为redis依赖

        <dependency>
            <groupId>com.example</groupId>
            <artifactId>common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

7、编写redis测试服务方法和消费方法

provider:

package com.example.provider.service;

public interface ProviderService {

    String sayHello2Consumer(String s);

    void setValue(String key, Object value, long time);

    String getValue(String key);

}
package com.example.provider.serviceImpl;

import com.example.common.redisCfg.RedisClient;
import com.example.provider.service.ProviderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class ProvideServiceImpl implements ProviderService {

    @Autowired
    private RedisClient redisClient;

    @Override
    public String sayHello2Consumer(String s) {
        System.out.println("provider s : " + s);
        return s;
    }

    /**
     * 设置key,value存入redis
     * 
     * @param key
     * @param value
     * @param time
     */
    @Override
    public void setValue(String key, Object value, long time) {
        redisClient.set(key, value, time);
    }

    /**
     * 根据key获取value
     * 
     * @param key
     * @return
     */
    @Override
    public String getValue(String key) {

        return redisClient.get(key) == null ? "redis key time out" : redisClient.get(key);
    }

}

consumer:

package com.example.consumer.controller;

import com.example.common.constants.Constants;
import com.example.provider.service.ProviderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConsumerController {

    @Autowired
    private ProviderService providerService;

    @GetMapping("/hello")
    public void sayHello(){
        String str = providerService.sayHello2Consumer("Not hello, just hi. ");
        System.out.println("consumer get str = " + str + " from provide");
    }

    @GetMapping("/setValue")
    public String setValue(String key, String value){
        //设置key有效时间为10s,便于测试
        providerService.setValue(key,value, Constants.CACHE_EXP_TEN_SECONDS);
        return "key: " + key +" value: " + value;
    }

    @GetMapping("/getValue")
    public String getValue(String key){
        return providerService.getValue(key);
    }

}

8、测试redis

接下来我们需要启动zookeeper,redis服务,然后再依次启动provider,consumer,确认一切运行正常,再打开postman接口测试工具以及redis客户端,一起来见证奇迹的发生!

(1)zookeeper,redis运行正常

 (2)provider,consumer运行正常

(3) 用postman调用接口:http://169.254.125.184:8081/setValue?key=hi&value=no hi, just hello

 (4)上边代码设置key的有效时间为10s,因此10s内查看redis客户端

 (5)10s内调用接口:http://169.254.125.184:8081/getValue?key=hi

(6)10s后调用接口: http://169.254.125.184:8081/getValue?key=hi

(7)10s后在redis客户端刷新一下

 

 

6.结语

至此,算是完结了

源码上传至GitHub,有需要者自取了:https://github.com/redesperado/MicroServiceDemo.git

本来还想学学如何使用kafka,但是配置了几次都失败了,果断放弃,大佬们有好的教程可以给我推荐推荐

 

最后大家来猜猜这篇博客写了多久吧。。。。。。 

  • 42
    点赞
  • 175
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
Spring Boot是一个开源的Java框架,用于快速构建独立的、基于Spring的应用程序。它简化了Spring应用程序的配置和部署过程,并提供了许多嵌入式服务器,如Tomcat、Jetty等。Spring Boot还提供了自动配置的特性,可以根据类路径中的依赖自动配置Spring应用程序。 Dubbo是一款高性能的分布式服务框架,也是阿里巴巴开源的项目。它提供了服务治理、远程通讯和分布式调用等功能,帮助开发人员轻松构建分布式服务化的应用。 Zookeeper是一个开源的分布式协调服务,可以用于实现分布式应用程序的一致性和可靠性。它提供了一个类似于文件系统的层次化的命名空间,并允许开发人员注册、协调和共享各种资源,如配置信息、服务注册和发现等。 当使用Spring Boot结合DubboZookeeper时,可以构建一个高性能、可扩展和可靠的微服务架构。Spring Boot提供了便利的开发和部署方式,Dubbo提供了分布式服务框架的支持,而Zookeeper则提供了分布式协调服务。开发人员可以使用Spring Boot快速构建独立的微服务应用程序,使用Dubbo进行服务间的通信和管理,同时通过Zookeeper进行服务的注册和发现。这样的架构可以方便地实现微服务架构中的资源共享和服务治理等功能,大大简化了开发人员的负担。 综上所述,Spring Boot结合DubboZookeeper可以构建高效、可靠的微服务架构,并提供了便利的开发和部署方式,帮助开发人员构建高性能的分布式应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值