• Spring Boot中使用Dubbo


    高并发下Redis会出现的问题:

    • 缓存穿透
    • 缓存雪崩
    • 热点缓存

    一、定义commons工程11-dubboCommons

    (1) 创建工程

    创建Maven的Java工程,并命名为11-dubboCommons

    (2) 定义pom文件

    1. <groupId>com.abc</groupId>
    2. <artifactId>11-dubboCommons</artifactId>
    3. <version>1.0-SNAPSHOT</version>
    4. <properties>
    5. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    6. <maven.compiler.source>1.8</maven.compiler.source>
    7. <maven.compiler.target>1.8</maven.compiler.target>
    8. </properties>
    9. <dependencies>
    10. <dependency>
    11. <groupId>org.projectlombok</groupId>
    12. <artifactId>lombok</artifactId>
    13. <version>1.18.4</version>
    14. <scope>provided</scope>
    15. </dependency>
    16. </dependencies>

    (3) 定义实体类

    (4) 定义业务接口

    (5) 将工程安装到本地库

    运行Maven的install命令,将工程安装到本地版本库,以备其它工程使用

    二、定义提供者11-provider-springboot

    (1) 创建工程

    创建一个Spring Boot工程,并重命名为11-provider-springboot

    (2) 定义pom文件

    A、添加dubbo与spring boot整合依赖
    B、添加zkClient依赖
    C、其它依赖

    • dubboCommons依赖
    • spring boot与redis整合依赖
    • mybatis与spring boot整合依赖
    • 数据源Druid依赖
    • mysql驱动依赖
    • slf4j-log4j12依赖
    • spring-boot-starter-web依赖
    1. <groupId>com.abc</groupId>
    2. <artifactId>11-provider-springboot</artifactId>
    3. <version>0.0.1-SNAPSHOT</version>
    4. <parent>
    5. <groupId>org.springframework.boot</groupId>
    6. <artifactId>spring-boot-starter-parent</artifactId>
    7. <version>2.1.5.RELEASE</version>
    8. <relativePath/> <!-- lookup parent from repository -->
    9. </parent>
    10. <properties>
    11. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    12. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    13. <java.version>1.8</java.version>
    14. </properties>
    15. <dependencies>
    16. <!--dubbo与spring boot整合依赖-->
    17. <dependency>
    18. <groupId>com.alibaba.spring.boot</groupId>
    19. <artifactId>dubbo-spring-boot-starter</artifactId>
    20. <version>2.0.0</version>
    21. </dependency>
    22. <!-- zk客户端依赖:zkclient -->
    23. <dependency>
    24. <groupId>com.101tec</groupId>
    25. <artifactId>zkclient</artifactId>
    26. <version>0.10</version>
    27. </dependency>
    28. <dependency>
    29. <groupId>com.abc</groupId>
    30. <artifactId>11-dubboCommons</artifactId>
    31. <version>1.0-SNAPSHOT</version>
    32. </dependency>
    33. <!--Spring Boot与Redis整合依赖-->
    34. <dependency>
    35. <groupId>org.springframework.boot</groupId>
    36. <artifactId>spring-boot-starter-data-redis</artifactId>
    37. </dependency>
    38. <!--mybatis与Spring Boot整合依赖-->
    39. <dependency>
    40. <groupId>org.mybatis.spring.boot</groupId>
    41. <artifactId>mybatis-spring-boot-starter</artifactId>
    42. <version>1.3.2</version>
    43. </dependency>
    44. <!--数据源Druid依赖-->
    45. <dependency>
    46. <groupId>com.alibaba</groupId>
    47. <artifactId>druid</artifactId>
    48. <version>1.1.10</version>
    49. </dependency>
    50. <!--MySQL驱动依赖-->
    51. <dependency>
    52. <groupId>mysql</groupId>
    53. <artifactId>mysql-connector-java</artifactId>
    54. <version>5.1.47</version>
    55. </dependency>
    56. <dependency>
    57. <groupId>org.slf4j</groupId>
    58. <artifactId>slf4j-log4j12</artifactId>
    59. <version>1.7.25</version>
    60. <scope>test</scope>
    61. </dependency>
    62. <dependency>
    63. <groupId>org.springframework.boot</groupId>
    64. <artifactId>spring-boot-starter-web</artifactId>
    65. </dependency>
    66. <dependency>
    67. <groupId>org.springframework.boot</groupId>
    68. <artifactId>spring-boot-starter-test</artifactId>
    69. <scope>test</scope>
    70. </dependency>
    71. </dependencies>
    72. <build>
    73. <plugins>
    74. <plugin>
    75. <groupId>org.springframework.boot</groupId>
    76. <artifactId>spring-boot-maven-plugin</artifactId>
    77. </plugin>
    78. </plugins>
    79. <resources>
    80. <!--注册dao包下mybatis映射文件为资源目录-->
    81. <resource>
    82. <directory>src/main/java</directory>
    83. <includes>
    84. <include>**/*.xml</include>
    85. </includes>
    86. </resource>
    87. </resources>
    88. </build>

    (3) 定义Service实现类

    1. import com.abc.bean.Employee;
    2. import com.abc.dao.EmployeeDao;
    3. import com.alibaba.dubbo.config.annotation.Service;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.cache.annotation.CacheEvict;
    6. import org.springframework.cache.annotation.Cacheable;
    7. import org.springframework.data.redis.core.BoundValueOperations;
    8. import org.springframework.data.redis.core.RedisTemplate;
    9. import org.springframework.stereotype.Component;
    10. import org.springframework.transaction.annotation.Transactional;
    11. import java.util.concurrent.TimeUnit;
    12. @Service // Dubbo的注解 <dubbo:service/>
    13. @Component
    14. public class EmployeeServiceImpl implements EmployeeService {
    15. @Autowired
    16. private EmployeeDao dao;
    17. @Autowired
    18. private RedisTemplate<Object, Object> redisTemplate;
    19. // 当有对象插入时会清空realTimeCache缓存空间
    20. @CacheEvict(value="realTimeCache", allEntries = true)
    21. @Transactional(rollbackFor = Exception.class)
    22. @Override
    23. public void addEmployee(Employee employee) {
    24. dao.insertEmployee(employee);
    25. }
    26. // 一旦有了查询结果,则会将此结果写入到realTimeCache缓存
    27. // key是employee_加上方法参数
    28. @Cacheable(value = {"realTimeCache"}, key = "'employee_'+#id")
    29. @Override
    30. public Employee findEmployeeById(int id) {
    31. // 从DB查询
    32. System.out.println("从DB查询id = " + id);
    33. return dao.selectEmployeeById(id);
    34. }
    35. private volatile Object count;
    36. // 双重检测锁机制解决Reids的热点缓存问题
    37. @Override
    38. public Integer findEmployeeCount() {
    39. // 获取Redis操作对象
    40. BoundValueOperations<Object, Object> ops = redisTemplate.boundValueOps("count");
    41. // 从缓存获取数据
    42. count = ops.get();
    43. if(count == null) {
    44. synchronized (this) {
    45. count = ops.get();
    46. if(count == null) {
    47. System.out.println("从DB中查询");
    48. // 从DB中查询
    49. count = dao.selectEmployeeCount();
    50. // 将查询结果存放到Redis
    51. ops.set(count, 10, TimeUnit.SECONDS);
    52. }
    53. }
    54. }
    55. return (Integer) count;
    56. }
    57. }

    (4) 定义Dao接口

    (5) 定义映射文件

    (6) 修改启动类

    在启动类上必须要添加@EnableDubboConfiguration注解,开启Dubbo的自动配置功能

    (7) 修改主配置文件

    1. server:
    2. port: 8888
    3. mybatis:
    4. # 注册mybatis中实体类的别名
    5. type-aliases-package: com.abc.bean
    6. # 注册映射文件
    7. mapper-locations: classpath:com/abc/dao/*.xml
    8. spring:
    9. # 注册数据源
    10. datasource:
    11. # 指定数据源类型为Druid
    12. type: com.alibaba.druid.pool.DruidDataSource
    13. driver-class-name: com.mysql.jdbc.Driver
    14. url: jdbc:mysql:///test?useUnicode=true&amp;characterEncoding=utf8
    15. username: root
    16. password: root
    17. # 连接Redis服务器
    18. redis:
    19. host: 39.97.176.160
    20. port: 6379
    21. # 连接Redis高可有集群
    22. # redis:
    23. # sentinel:
    24. # master: mymaster
    25. # nodes:
    26. # - sentinelOS1:26379
    27. # - sentinelOS2:26379
    28. # - sentinelOS3:26379
    29. # 配置缓存
    30. cache:
    31. type: redis # 指定缓存类型
    32. cache-names: realTimeCache # 指定缓存区域名称
    33. # 功能等价于spring-boot配置文件中的<dubbo:application/>
    34. application:
    35. name: 11-provider-springboot
    36. # 指定zk注册中心
    37. dubbo:
    38. registry: zookeeper://39.97.176.160:2181
    39. # zk集群作注册中心
    40. # registry: zookeeper://zkOS1:2181?backup=zkOS2:2181,zkOS3:2181

    三、定义消费者11-consumer-springboot

    (1) 创建工程

    创建一个Spring Boot工程,并重命名为11-consumer-springboot

    (2) 定义pom文件

    • dubbo与spring boot整合依赖
    • zkClient依赖
    • dubboCommons依赖
    • JSP引擎jasper依赖
    • slf4j-log4j12依赖
    • spring-boot-starter-web依赖

    (3) 修改主配置文件

    1. spring:
    2. # 功能等价于spring-dubbo配置文件中的<dubbo:application/>
    3. application:
    4. name: 11-consumer-springboot
    5. # 指定zk注册中心
    6. dubbo:
    7. registry: zookeeper://39.97.176.160:2181
    8. # zk集群作注册中心
    9. # registry: zookeeper://zkOS1:2181?backup=zkOS2:2181,zkOS3:2181

    (4) 创建index.jsp页面

    在src/main/webapp目录下定义index.jsp文件

    (5) 定义处理器

    1. package com.abc.controller;
    2. import com.abc.bean.Employee;
    3. import com.abc.service.EmployeeService;
    4. import com.alibaba.dubbo.config.annotation.Reference;
    5. import org.springframework.stereotype.Controller;
    6. import org.springframework.ui.Model;
    7. import org.springframework.web.bind.annotation.PathVariable;
    8. import org.springframework.web.bind.annotation.PostMapping;
    9. import org.springframework.web.bind.annotation.RequestMapping;
    10. import org.springframework.web.bind.annotation.ResponseBody;
    11. @Controller
    12. @RequestMapping("/consumer/employee")
    13. public class SomeController {
    14. // @Autowired
    15. @Reference // Dubbo的注解 <dubbo:reference />
    16. private EmployeeService employeeService;
    17. @PostMapping("/register")
    18. public String someHandle(Employee employee, Model model) {
    19. employeeService.addEmployee(employee);
    20. model.addAttribute("employee", employee);
    21. return "/welcome.jsp";
    22. }
    23. @RequestMapping("/find/{id}")
    24. @ResponseBody
    25. public Employee findHandle(@PathVariable("id") int id) {
    26. return employeeService.findEmployeeById(id);
    27. }
    28. @RequestMapping("/count")
    29. @ResponseBody
    30. public Integer countHandle() {
    31. return employeeService.findEmployeeCount();
    32. }
    33. }

    (6) 定义welcome.jsp页面

    (7) 修改入口类

    四、测试

    当有对象插入时会清空realTimeCache缓存空间
    一旦有了查询结果,则会将此结果写入到realTimeCache缓存

    http://localhost:8080/index.jsp  首页

    http://localhost:8080//consumer/employee/find/2 根据Id查找

    http://localhost:8080//consumer/employee/count 查找总数

  • 相关阅读:
    使用idea15搭建基于maven的springmvc-mybatis框架
    git本地提交到远程仓库命令
    jsp表格数据导出到Execl
    FreeMarker标签介绍
    FreeMarker常用语法
    mybatis批量删除
    git之https或http方式设置记住用户名和密码的方法
    INPUT只能输入数字
    mysql 日期格式化
    cygwin配置git
  • 原文地址:https://www.cnblogs.com/edda/p/13260451.html
Copyright © 2020-2023  润新知