手写RPC框架(二十)

v2.11

这是个大工程 将自己的用户中心改造一块 当作rpc的监控中心,同时尝试能否将服务降级等相关的方法也完善,之后还有什么歌曲管理中心等 大伙在使用我这块的同时 可以用下我的用户中心项目

  • 用户中心改造成监控中心

    • 设计监控中心对应数据库

      create table rpc_monitor
      (
          id            bigint auto_increment comment 'id' primary key,
          method_name     varchar(256)                       null comment '方法名称',
          method_description     varchar(256)                       null comment '方法描述',
          call_time   datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '调用时间',
          call_num   int      default 0                 not null comment '方法调用次数'
      )
      
    • 前端将原来的界面调整 新增监控界面 有点为难我了 这块 但是为了完整性拼了

      实现界面
      在这里插入图片描述

    • 在我的用户中心简易的编写一下后端的逻辑之后进行完善 相应数据库的类 就用mybatisX生成了

      /**
       * @Author 祝英台炸油条
       * @Time : 2022/6/3 14:12
       **/
      @RestController
      @RequestMapping("/method")
      public class RpcMonitorController {
      
          @Resource
          private RpcMonitorService rpcMonitorService;
      
          @GetMapping("/search")
          public BaseResponse<List<RpcMonitor>> methodSearch() {
              return ResultUtils.success(rpcMonitorService.list());
          }
      }
      
    • 到rpc框架编写相应的逻辑 当服务被调用的时候 相应的进行修改 同时当服务提供方停止后又重新启动时 需将数据库中数据清空

      • 首先要与数据库进行操作 必须要有持久层 数据库连接池 jdbc 或者 mybatis等。第一步引入依赖

        <!--数据库连接池-->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <scope>runtime</scope>
                </dependency>
        
                <!--mybatis用来和数据库进行交互-->
                <dependency>
                    <groupId>org.mybatis.spring.boot</groupId>
                    <artifactId>mybatis-spring-boot-starter</artifactId>
                    <version>2.1.4</version>
                </dependency>
                <dependency>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-boot-starter</artifactId>
                    <version>3.5.1</version>
                </dependency>
        
        
      • 目前只进行了netty版本的修改)接下来 最简单的 我的想法是每次启动的时候 就将原先的数据库中的字段全部清空 然后把所有的服务还有对应的地址注册进去,在每次调用的同时 进行数据的新增

      • 遇到bug 一直空指针异常 mybatis还是差的太多了 回来好好写 问题:我觉得是我不能按照和springboot整合的方式进行整合 因为整合的时候 用properties 这只能作用于springboot//@Autowired不能作用于静态对象 //真实原因就是我不是springboot

      • 采用spring整合mybatis 属于就是回到最开始的地方 回顾一下之前的东西

      • 遇到bug 依赖的重复引用 会导致找不到一些 jar这时候 就是要减少部分依赖

      • 如果我们在项目中配置的driver-class-name为com.mysql.jdbc.Driver,则对应的mysql-connector-java版本应该是5.x。

        如果我们在项目中配置的driver-class-name为com.mysql.cj.jdbc.Driver,则对应的mysql-connector-java版本应该是8.x。

      • 成功终于整合了mybatis-plus和spring mybatis-plus-samples/mybatis-plus-sample-quickstart-springmvc at master · baomidou/mybatis-plus-samples (github.com) 参考

    • 整合配置文件和引入依赖

      • 配置文件

        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        
            <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
                <property name="basePackage" value="provider.monitor.mapper"/>
            </bean>
        
            <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
                <property name="dataSource" ref="dataSource"/>
            </bean>
        
            <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
                <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
                <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/zeng?serverTimezone=UTC"/>
                <property name="user" value="root"/>
                <property name="password" value="root"/>
            </bean>
        
        </beans>
        
      • 引入依赖

         <!--数据库连接池-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <!-- 数据库连接池:c3p0-->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
        
        <!--mybatis用来和数据库进行交互-->
        
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.4.3.4</version>
        </dependency>
        
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.15.RELEASE</version>
        </dependency>
        
    • 进行相应的方法设置 因为我们的方法都是通过main方法进行的 该方法是由static修饰的 我们使用@AutoWried什么的不能用static 所以我采用使其在其他类中创建对应方法 我再引用即可

      • 将监控类的初始化 改为类加载,在整个运行过程中 只加载一次 有效的减少了相应的消耗

         static RpcMonitorMapper rpcMonitorMapper;
        
        static {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-mybatis.xml");
            rpcMonitorMapper = context.getBean(RpcMonitorMapper.class);
        }
        
      • 删除方法

        /**
        * 作用 就是每次开启服务提供商的时候 删除掉所有的对应项目
        */
        public void deleteAll() {
            rpcMonitorMapper.delete(null);
        }
        
      • 添加方法

        /**
        * 每次开启服务的时候 就进行添加对应的服务 当然 起始调用次数为0
        */
        public void addServer(RpcMonitor rpcMonitorServer) {
            rpcMonitorMapper.insert(rpcMonitorServer);
        }
        
      • 更改方法

        /**
             * 更新相应的服务  将相应的服务调用次数+1  同时update的时候  会自动的更改调用时间  做这个的时候 要上锁 防止线程冲突
             */
        public synchronized void updateServer(String methodAddress) {
            QueryWrapper<RpcMonitor> wrapper = new QueryWrapper<>();
            // 没问题 查询的时候 是跟对应的列名进行比较 
            wrapper.eq("method_name",methodAddress);
            RpcMonitor rpcMonitor = rpcMonitorMapper.selectOne(wrapper);
            if (rpcMonitor==null) try {
                throw new RpcException("监控中心出现错误");
            } catch (RpcException e) {
                log.error(e.getMessage(),e);
                return;
            }
            rpcMonitor.setCallNum(rpcMonitor.getCallNum()+1);
            rpcMonitorMapper.update(rpcMonitor,new QueryWrapper<RpcMonitor>().eq("id",rpcMonitor.getId()));
        }
        
    • 再对应的地方 进行相应方法的调用

      • 服务端 一开始将原先的数据库进行清空

        RpcMonitorOperator rpcMonitorOperator = new RpcMonitorOperator();
        rpcMonitorOperator.deleteAll();
        
      • 服务端 一开始将所有的注册进去 还有就是端口的问题

         RpcMonitor rpcMonitor = new RpcMonitor();
                        //TODO 这里之后还可以继续进行更改 因为这块的话 如果放在服务器上 那么就可以采用服务器相关的设置
                        rpcMonitor.setMethodName("127.0.0.1:"+ port);
                        rpcMonitor.setMethodDescription(methodName);
                        rpcMonitorOperator.addServer(rpcMonitor);
                        int nowPort = port.get();
                        //因为下面这个开启一个线程 会慢一点
                        new Thread(() -> NettyServer24.start(methodName, nowPort)).start();
                        port.incrementAndGet();
        
      • 客户端 将调用的服务进行 增加调用次数

        RpcMonitorOperator rpcMonitorOperator = new RpcMonitorOperator();
        rpcMonitorOperator.updateServer(methodAddress);
        

效果图

在这里插入图片描述

热更新两个加菜

进行一些判断逻辑上的优化,解决日志乱码问题

  • 例如传入方法和启动相应的服务器数量不一致等逻辑
  • 解决日志乱码问题
    • 在相应的配置文件上配置GBK
      在这里插入图片描述

将依赖版本都升级到最新 旧版都能运行的备注了 如果读者用到哪个无法使用的时候 可以使用旧版

更新整合配置 将数据库的信息提取 方便更改

  • 数据库信息整合入properties 通过el表达式提取

    <?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: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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!-- Import Properties -->
        <context:property-placeholder location="classpath:db.properties"/>
    
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="monitor.mapper"/>
        </bean>
    
        <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
        </bean>
    
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="${jdbc.driver}"/>
            <property name="jdbcUrl" value="${jdbc.url}"/>
            <property name="user" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        </bean>
    </beans>
    
     
     w#自测版本
    jdbc.url=jdbc:mysql://localhost:3306/zeng?serverTimezone=UTC
    jdbc.username=root
    jdbc.password=root
    jdbc.driver=com.mysql.cj.jdbc.Driver
    
    
    #连接外部数据库版本
    #jdbc.url=jdbc:mysql://121.43.39.136:3306/zeng?serverTimezone=UTC
    #jdbc.username=zyt
    #jdbc.password=zyt
    #jdbc.driver=com.mysql.cj.jdbc.Driver
    
  • 在服务器数据库上建表 然后将前端部署 这样可以直接通过自己的域名监控调用次数

  • 部署的时候 出现问题 前端在搜索调用方法的时候 出现404 但明明搜索用户也没错啊

    GET https://user-backend.onlyicanstopmyself.top/api/method/search 404
    

    解决方法:问题并不出在前端或者是后端上面 而是自己在宝塔上重新上传了jar包 然后没有重新运行,这是不该犯的错,一定要精通部署这块
    在这里插入图片描述

  • 部署成功 效果也正确 出现新的问题 当继续进行修改之后时间并没有修改

    • 解决:每次进行修改的同时 将调用时间置空 这块不需要重新部署 因为只是自身逻辑这块有问题
      在这里插入图片描述
  • 出现新问题 前端显示时间和数据库差8个小时 目前查到原因是去读取的时候 发现有时差

    • 解决:通过修改连接数据库的url 需要和我们的数据库的时区一致 否则不同时区 会发生相应的改变 一些增加和减少时间的现象

      url: jdbc:mysql://121.43.39.136:3306/zeng?serverTimezone=GMT%2B8
      
  • 前端bug 如果没有用户名则右上角菜单会不断读取

    • 解决:更改数据库名段 将默认名称设为visitor
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值