<dfn id="hx5t3"><strike id="hx5t3"><em id="hx5t3"></em></strike></dfn>

    <thead id="hx5t3"></thead><nobr id="hx5t3"><font id="hx5t3"><rp id="hx5t3"></rp></font></nobr>

    <listing id="hx5t3"></listing>

    <var id="hx5t3"></var>
    <big id="hx5t3"></big>

      
      

      <output id="hx5t3"><ruby id="hx5t3"></ruby></output>
      <menuitem id="hx5t3"><dfn id="hx5t3"></dfn></menuitem>

      <big id="hx5t3"></big>

        isWulongbo

        isWulongbo 查看完整檔案

        深圳編輯Sapporo City University  |  計算機科學與技術 編輯把把智能  |  JAVA工程師 編輯 www.wulongbo.com 編輯
        編輯

        在人生的頭三十年,你培養習慣,后三十年,習慣鑄就你
        一起交流學習請加微信:1191935532

        個人動態

        isWulongbo 發布了文章 · 3月3日

        Kibana啟動

        #root用戶啟動
        bin/kibana --allow-root 
        
        #非root用戶啟動
        bin/kibana 
        檢查 logstash 配置文件是否正確
        bin/logstash -f config/log_config.conf -t
        查看原文

        贊 0 收藏 0 評論 0

        isWulongbo 發布了文章 · 3月2日

        Redis生成訂單號格式化補0

        工具類

        RedisUtil:

        package com.spring.security.demo.utils.redis;
        import com.spring.security.demo.utils.CollectionUtils;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.data.redis.connection.RedisConnectionFactory;
        import org.springframework.data.redis.core.RedisTemplate;
        import org.springframework.data.redis.support.atomic.RedisAtomicLong;
        import org.springframework.stereotype.Component;
        import java.util.List;
        import java.util.Map;
        import java.util.Set;
        import java.util.concurrent.TimeUnit;
        @Component
        public class RedisUtil {
            @Autowired
         private RedisTemplate<String, Object> redisTemplate;
         /**
         * 獲取訂單號
         *
         * @param key key
         */ public String getOrderId(String key) {
                String orderNum="";
         try {
                    RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
         RedisAtomicLong redisAtomicLong = new RedisAtomicLong(key, factory);
         // redis設置初始值
         redisAtomicLong.set(1);
         // 設置步長加10
         redisAtomicLong.addAndGet(10);
         Long incrementAndGet = redisAtomicLong.incrementAndGet();
         orderNum = String.format("%1$05d", incrementAndGet);
         } catch (Exception e) {
                    return orderNum;
         }
                return orderNum;
         }
            /**
         * 存放string類型
         *
         * @param key key
         * @param data 數據
         * @param timeout 超時間
         */
         public void setString(String key, String data, Long timeout) {
                try {
                    redisTemplate.opsForValue().set(key, data);
         if (timeout != null) {
                        redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
         }
                } catch (Exception e) {
                }
            }
            /**
         * 開啟Redis 事務
         *
         * @param
         */
         public void begin() {
                // 開啟Redis 事務權限
         redisTemplate.setEnableTransactionSupport(true);
         // 開啟事務
         redisTemplate.multi();
         }
            /**
         * 提交事務
         *
         * @param
         */
         public void exec() {
                // 成功提交事務
         redisTemplate.exec();
         }
            /**
         * 回滾Redis 事務
         */
         public void discard() {
                redisTemplate.discard();
         }
            // =============================common============================
         /**
         * 指定緩存失效時間
         *
         * @param key 鍵
         * @param time 時間(秒)
         * @return
         */
         public boolean expire(String key, long time) {
                try {
                    if (time > 0) {
                        redisTemplate.expire(key, time, TimeUnit.SECONDS);
         }
                    return true;
         } catch (Exception e) {
                    e.printStackTrace();
         return false; }
            }
            /**
         * 根據key 獲取過期時間
         *
         * @param key 鍵 不能為null
         * @return 時間(秒) 返回0代表為永久有效
         */
         public long getExpire(String key) {
                return redisTemplate.getExpire(key, TimeUnit.SECONDS);
         }
            /**
         * 判斷key是否存在
         *
         * @param key 鍵
         * @return true 存在 false不存在
         */
         public boolean hasKey(String key) {
                try {
                    return redisTemplate.hasKey(key);
         } catch (Exception e) {
                    e.printStackTrace();
         return false; }
            }
            /**
         * 刪除緩存
         *
         * @param key 可以傳一個值 或多個
         */
         @SuppressWarnings("unchecked")
            public void del(String... key) {
                if (key != null && key.length > 0) {
                    if (key.length == 1) {
                        redisTemplate.delete(key[0]);
         } else {
                        redisTemplate.delete(CollectionUtils.arrayToList(key));
         }
                }
            }
            // ============================String=============================
         /**
         * 普通緩存獲取
         *
         * @param key 鍵
         * @return 值
         */
         public Object get(String key) {
                return key == null ? null : redisTemplate.opsForValue().get(key);
         }
            /**
         * 普通緩存放入
         *
         * @param key 鍵
         * @param value 值
         * @return true成功 false失敗
         */
         public boolean set(String key, Object value) {
                try {
                    redisTemplate.opsForValue().set(key, value);
         return true; } catch (Exception e) {
                    e.printStackTrace();
         return false; }
            }
            /**
         * 普通緩存放入并設置時間
         *
         * @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 > 0) {
                        redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
         } else {
                        set(key, value);
         }
                    return true;
         } catch (Exception e) {
                    e.printStackTrace();
         return false; }
            }
            /**
         * 根據key查詢string類型
         *
         * @param key
         * @return
         */
         public Object getString(String key) {
                Object value = redisTemplate.opsForValue().get(key);
         return value;
         }
            /**
         * 遞增
         *
         * @param key 鍵
         * @param delta 要增加幾(大于0)
         * @return
         */
         public long incr(String key, long delta) {
                if (delta < 0) {
                    throw new RuntimeException("遞增因子必須大于0");
         }
                return redisTemplate.opsForValue().increment(key, delta);
         }
            /**
         * 遞減
         *
         * @param key 鍵
         * @param delta 要減少幾(小于0)
         * @return
         */
         public long decr(String key, long delta) {
                if (delta < 0) {
                    throw new RuntimeException("遞減因子必須大于0");
         }
                return redisTemplate.opsForValue().increment(key, -delta);
         }
            // ================================Map=================================
         /**
         * HashGet * * @param key 鍵 不能為null
         * @param item 項 不能為null
         * @return 值
         */
         public Object hget(String key, String item) {
                return redisTemplate.opsForHash().get(key, item);
         }
            /**
         * 獲取hashKey對應的所有鍵值
         *
         * @param key 鍵
         * @return 對應的多個鍵值
         */
         public Map<Object, Object> hmget(String key) {
                return redisTemplate.opsForHash().entries(key);
         }
            /**
         * HashSet * * @param key 鍵
         * @param map 對應多個鍵值
         * @return true 成功 false 失敗
         */
         public boolean hmset(String key, Map<String, Object> map) {
                try {
                    redisTemplate.opsForHash().putAll(key, map);
         return true; } catch (Exception e) {
                    e.printStackTrace();
         return false; }
            }
            /**
         * HashSet 并設置時間
         *
         * @param key 鍵
         * @param map 對應多個鍵值
         * @param time 時間(秒)
         * @return true成功 false失敗
         */
         public boolean hmset(String key, Map<String, Object> map, long time) {
                try {
                    redisTemplate.opsForHash().putAll(key, map);
         if (time > 0) {
                        expire(key, time);
         }
                    return true;
         } catch (Exception e) {
                    e.printStackTrace();
         return false; }
            }
            /**
         * 向一張hash表中放入數據,如果不存在將創建
         *
         * @param key 鍵
         * @param item 項
         * @param value 值
         * @return true 成功 false失敗
         */
         public boolean hset(String key, String item, Object value) {
                try {
                    redisTemplate.opsForHash().put(key, item, value);
         return true; } catch (Exception e) {
                    e.printStackTrace();
         return false; }
            }
            /**
         * 向一張hash表中放入數據,如果不存在將創建
         *
         * @param key 鍵
         * @param item 項
         * @param value 值
         * @param time 時間(秒) 注意:如果已存在的hash表有時間,這里將會替換原有的時間
         * @return true 成功 false失敗
         */
         public boolean hset(String key, String item, Object value, long time) {
                try {
                    redisTemplate.opsForHash().put(key, item, value);
         if (time > 0) {
                        expire(key, time);
         }
                    return true;
         } catch (Exception e) {
                    e.printStackTrace();
         return false; }
            }
            /**
         * 刪除hash表中的值
         *
         * @param key 鍵 不能為null
         * @param item 項 可以使多個 不能為null
         */ public void hdel(String key, Object... item) {
                redisTemplate.opsForHash().delete(key, item);
         }
            /**
         * 判斷hash表中是否有該項的值
         *
         * @param key 鍵 不能為null
         * @param item 項 不能為null
         * @return true 存在 false不存在
         */
         public boolean hHasKey(String key, String item) {
                return redisTemplate.opsForHash().hasKey(key, item);
         }
            /**
         * hash遞增 如果不存在,就會創建一個 并把新增后的值返回
         *
         * @param key 鍵
         * @param item 項
         * @param by 要增加幾(大于0)
         * @return 274
         */ public double hincr(String key, String item, double by) {
                return redisTemplate.opsForHash().increment(key, item, by);
         }
            /**
         * hash遞減
         *
         * @param key 鍵
         * @param item 項
         * @param by 要減少記(小于0)
         * @return 285
         */ public double hdecr(String key, String item, double by) {
                return redisTemplate.opsForHash().increment(key, item, -by);
         }
            // ============================set=============================
         /**
         * 根據key獲取Set中的所有值
         *
         * @param key 鍵
         * @return 295
         */ public Set<Object> sGet(String key) {
                try {
                    return redisTemplate.opsForSet().members(key);
         } catch (Exception e) {
                    e.printStackTrace();
         return null; }
            }
            /**
         * 根據value從一個set中查詢,是否存在
         *
         * @param key 鍵
         * @param value 值
         * @return true 存在 false不存在
         */
         public boolean sHasKey(String key, Object value) {
                try {
                    return redisTemplate.opsForSet().isMember(key, value);
         } catch (Exception e) {
                    e.printStackTrace();
         return false; }
            }
            /**
         * 將數據放入set緩存
         *
         * @param key 鍵
         * @param values 值 可以是多個
         * @return 成功個數
         */
         public long sSet(String key, Object... values) {
                try {
                    return redisTemplate.opsForSet().add(key, values);
         } catch (Exception e) {
                    e.printStackTrace();
         return 0;
         }
            }
            /**
         * 336 * 將set數據放入緩存
         * 337
         * * @param key 鍵
         *               338
         * @param time 時間(秒)
         *               339 * @param values 值 可以是多個
         *               340
         * @return 成功個數
         * 341
         */
         public long sSetAndTime(String key, long time, Object... values) {
                try {
                    Long count = redisTemplate.opsForSet().add(key, values);
         if (time > 0)
                        expire(key, time);
         return count;
         } catch (Exception e) {
                    e.printStackTrace();
         return 0;
         }
            }
            /**
         * 355 * 獲取set緩存的長度
         * 356
         * * @param key 鍵
         *            357
         * @return 358
         */
         public long sGetSetSize(String key) {
                try {
                    return redisTemplate.opsForSet().size(key);
         } catch (Exception e) {
                    e.printStackTrace();
         return 0;
         }
            }
            /**
         * 369 * 移除值為value的
         * 370
         * * @param key 鍵
         *               371
         * @param values 值 可以是多個
         *               372
         * @return 移除的個數
         * 373
         */
         public long setRemove(String key, Object... values) {
                try {
                    Long count = redisTemplate.opsForSet().remove(key, values);
         return count;
         } catch (Exception e) {
                    e.printStackTrace();
         return 0;
         }
            }
            // ===============================list=================================
         /**
         * 386 * 獲取list緩存的內容
         * 387
         * * @param key 鍵
         *              388
         * @param start 開始
         *              389
         * @param end 結束 0 到 -1代表所有值
         *              390
         * @return 391
         */
         public List<Object> lGet(String key, long start, long end) {
                try {
                    return redisTemplate.opsForList().range(key, start, end);
         } catch (Exception e) {
                    e.printStackTrace();
         return null;
         }
            }
            /**
         * 402 * 獲取list緩存的長度
         * 403
         * * @param key 鍵
         *            404
         * @return 405
         */
         public long lGetListSize(String key) {
                try {
                    return redisTemplate.opsForList().size(key);
         } catch (Exception e) {
                    e.printStackTrace();
         return 0;
         }
            }
            /**
         * 416 * 通過索引 獲取list中的值
         * 417
         * * @param key 鍵
         *              418
         * @param index 索引 index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數第二個元素,依次類推
         *              419
         * @return 420
         */
         public Object lGetIndex(String key, long index) {
                try {
                    return redisTemplate.opsForList().index(key, index);
         } catch (Exception e) {
                    e.printStackTrace();
         return null;
         }
            }
            /**
         * 431 * 將list放入緩存
         * 432
         * * @param key 鍵
         *              433
         * @param value 值
         *              434
         * @param time 時間(秒)
         *              435 * @return 436
         */
         public boolean lSet(String key, Object value) {
                try {
                    redisTemplate.opsForList().rightPush(key, value);
         return true;
         } catch (Exception e) {
                    e.printStackTrace();
         return false;
         }
            }
            /**
         * 將list放入緩存
         *
         * @param key 鍵
         * @param value 值
         * @param time 時間(秒)
         * @return
         */
         public boolean lSet(String key, Object value, long time) {
                try {
                    redisTemplate.opsForList().rightPush(key, value);
         if (time > 0)
                        expire(key, time);
         return true;
         } catch (Exception e) {
                    e.printStackTrace();
         return false;
         }
            }
            /**
         * 467 * 將list放入緩存
         * 468
         * * @param key 鍵
         *              469
         * @param value 值
         *              470
         * @param time 時間(秒)
         *              471 * @return 472
         */
         public boolean lSet(String key, List<Object> value) {
                try {
                    redisTemplate.opsForList().rightPushAll(key, value);
         return true;
         } catch (Exception e) {
                    e.printStackTrace();
         return false;
         }
            }
            /**
         * 484 * 將list放入緩存
         * 485
         * <p>
         * 486
         * * @param key 鍵
         *              487
         * @param value 值
         *              488
         * @param time 時間(秒)
         *              489 * @return 490
         */
         public boolean lSet(String key, List<Object> value, long time) {
                try {
                    redisTemplate.opsForList().rightPushAll(key, value);
         if (time > 0)
                        expire(key, time);
         return true;
         } catch (Exception e) {
                    e.printStackTrace();
         return false;
         }
            }
            /**
         * 504 * 根據索引修改list中的某條數據
         * 505
         * * @param key 鍵
         *              506
         * @param index 索引
         *              507
         * @param value 值
         *              508
         * @return 509
         */
         public boolean lUpdateIndex(String key, long index, Object value) {
                try {
                    redisTemplate.opsForList().set(key, index, value);
         return true;
         } catch (Exception e) {
                    e.printStackTrace();
         return false;
         }
            }
            /**
         * 521 * 移除N個值為value
         * 522 * * @param key 鍵
         *              523
         * @param count 移除多少個
         *              524
         * @param value 值
         *              525
         * @return 移除的個數
         * 526
         */
         public long lRemove(String key, long count, Object value) {
                try {
                    Long remove = redisTemplate.opsForList().remove(key, count, value);
         return remove;
         } catch (Exception e) {
                    e.printStackTrace();
         return 0;
         }
            }
        }

        控制器Controller:

        @Autowired
        private RedisUtil redisUtil;
        
        /**
         * 獲取自增訂單號
         *
         * @param key
         * @return
         */
        @ApiOperation(value = "獲取自增訂單號", notes = "獲取自增訂單號")
        @ApiImplicitParams({
                @ApiImplicitParam(paramType = "query", name = "key", dataType = "String", required = true, value = "key")})
        @PostMapping("/getOrderNum")
        public String getOrderNum(String key) {
            String orderId = "訂單號不存在";
         try {
                orderId = prefix() + "-" + redisUtil.getOrderId(key);
         } catch (Exception e) {
                e.printStackTrace();
         }
            return orderId;
        }
        public static String prefix() {
            String temp_str = "";
         Date date = new Date();
         SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
         temp_str = sdf.format(date);
         return temp_str;
        }

        補充一下Redis事務:RedisDataSoureceTransaction

        package com.spring.security.demo.utils.transaction;
        import com.spring.security.demo.utils.redis.RedisUtil;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
        import org.springframework.context.annotation.Scope;
        import org.springframework.stereotype.Component;
        import org.springframework.transaction.PlatformTransactionManager;
        import org.springframework.transaction.TransactionStatus;
        import org.springframework.transaction.annotation.EnableTransactionManagement;
        import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
        @EnableTransactionManagement
        @Component
        @Scope(ConfigurableListableBeanFactory.SCOPE_PROTOTYPE)
        public class RedisDataSoureceTransaction {
           @Autowired
         private RedisUtil redisUtil;
         /**
         * 數據源事務管理器
         */
         @Autowired
         private PlatformTransactionManager dataSourceTransactionManager;
         /**
         * 開始事務 采用默認傳播行為
         * 
        * @return
         */
         public TransactionStatus begin() {
              // 手動begin數據庫事務
         // 1.開啟數據庫的事務 事務傳播行為
         TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
         // 2.開啟redis事務
         redisUtil.begin();
         return transaction;
         }
           /**
         * 提交事務
         * 
        * @param transactionStatus
         * 事務傳播行為
         * @throws Exception
         */ public void commit(TransactionStatus transactionStatus) throws Exception {
              if (transactionStatus == null) {
                 throw new Exception("transactionStatus is null");
         }
              // 支持Redis與數據庫事務同時提交
         dataSourceTransactionManager.commit(transactionStatus);
         }
           /**
         * 回滾事務
         * 
        * @param transactionStatus
         * @throws Exception
         */ public void rollback(TransactionStatus transactionStatus) throws Exception {
              if (transactionStatus == null) {
                 throw new Exception("transactionStatus is null");
         }
              // 1.回滾數據庫事務 redis事務和數據庫的事務同時回滾
         dataSourceTransactionManager.rollback(transactionStatus);
         // // 2.回滾redis事務
         // redisUtil.discard();
         }
           // 如果redis的值與數據庫的值保持不一致話
        }
        查看原文

        贊 0 收藏 0 評論 0

        isWulongbo 發布了文章 · 3月2日

        Mysql 插入或者修改(insertOrUpdate)

        備注遇到的坑

        接口:

        /**
         * 插入或者修改黑白名單列表
         * @param contactBook
         * @return
         */
        boolean insertOrUpdate(@Param("contactBook") ContactBook contactBook);

        實現類:

        /**
         * 插入或者修改黑白名單列表
         * @param contactBook
         * @return
         */
        @Override
        public boolean insertOrUpdate(ContactBook contactBook) {
            return this.baseMapper.insertOrUpdate(contactBook);
        }

        Mapper:

        /**
         * 插入或者修改黑白名單列表
         * @param contactBook
         * @return
         */
        boolean insertOrUpdate(@Param("contactBook") ContactBook contactBook);

        Mapper.xml:

        <insert id="insertOrUpdate" parameterType="com.spring.security.demo.entity.ContactBook">
         INSERT INTO `tbl_contact_book`(`imei`, `contact_list`, `ability`, `create_time`, `update_time`)
             VALUES
         (#{contactBook.imei}, #{contactBook.contactList}, #{contactBook.ability},#{contactBook.updateTime}, #{contactBook.updateTime})
          ON DUPLICATE KEY UPDATE contact_list = values(contact_list),ability = values(ability),update_time =  values(update_time)
        </insert>

        注意:這里(ON DUPLICATE KEY UPDATE 后面)更新字段的必須和數據庫字段名一致。
        image.png

        查看原文

        贊 0 收藏 0 評論 0

        isWulongbo 發布了文章 · 2月25日

        使用Jenkins實現自動化部署

        前言

        我的centos服務器以及安裝好了docker的,下面直接開始安裝Jenkins

        安裝Jenkins

        • 查看docker版本
        docker -v
        • docker 所有 image 文件
        docker image ls
        • 啟動 docker
        # service 命令的用法 $ sudo service docker start
        # systemctl 命令的用法 $ sudo systemctl start docker

        image.png

        這里把Jenkins默認8080端口修改為8040
        安裝成功后:訪問 http://39.102.56.91:8040/【賬號為wulongbo,密碼為wulongbo945108】
        image.png

        Jenkins配置

        環境配置

        image.png
        image.png
        這里 JAVA_HOME路徑 我們從服務器查

        • 首先進入jenkins docker容器
        docker exec -it jenkins /bin/bash
        • 查看 java 版本
        java -version
        • 查看jdk的安裝目錄
        echo $JAVA_HOME

        image.png

        • 安裝maven

        image.png

        • 安裝maven插件 Maven Integration

        image.png
        image.png

        • 等待安裝完畢后重啟!

        image.png

        • 新建任務

        image.png
        image.png

        • 配置

        image.png
        image.png

        • 添加 Credentials

        image.png

        • 選擇剛剛添加的賬號密碼

        image.png

        • 添加打包命令

        image.png

        • 保存
        • 立即構建

        image.png

        • 點擊進度條進入控制臺

        image.png

        • 構建成功

        image.png

        • docker Jenkins容器尋找到jar包

        image.png

        image.png

        • 自動化運行腳本【點擊項目-->配置】

        image.png

        • 引入shell 腳本

        image.png
        JAR_PATHJAR_WORK_PATH路徑填寫按如下截圖尋找進入控制臺copy
        image.png
        image.png

        #!/bin/bash
        ## 服務名稱(最好和發布名稱相同)
        SERVER_NAME=wulongbo
        ## 源jar路徑,mvn打包完成之后,target目錄下的jar包名稱,也可以選擇war包,war包可以選擇移動到tomcat的web-info下
        JAR_NAME=springboot_son-0.0.1-SNAPSHOT
        ## 源jar路徑
        ## demo項目目錄
        ## target打包生成jar包的目錄
        JAR_PATH=/var/jenkins_home/workspace/wulongbo/target
        ## 打包完成之后把jar包移動到運行jar包的目錄,work_deamon,work_deamon這個目錄需要自己提前創建
        JAR_WORK_PATH=/var/jenkins_home/workspace/wulongbo/target/
        
        echo "查詢進程id-->$SERVER_NAME"
        PID=`ps -ef | grep "SERVER_NAME" | awk '{print $2}'` 
        echo "得到進程id: $PID"
        echo "結束進程"
        for id in $PID
        do
            kill -9 $id
        done
        echo "結束進程完成"
        
        ##復制jar包到執行目錄
        echo "復制jar包到執行目錄:cp $JAR_PATH/$JAR_NAME.jar $JAR_WORK_PATH"
        echo "復制jar包完成"
        cd $JAR_WORK_PATH
        ## 修改文件權限
        chmod 755 $JAR_NAME.jar
        java -jar $JAR_NAME.jar
        • 保存
        • 重新構建

        image.png

        • 點擊控制臺,看到項目啟動成功

        image.png

        image.png
        curl 127.0.0.1:8012 查看容器內是否運行
        因為Jenkins 是通過容器部署,需要我們把端口號映射出來

        • 停掉容器
        systemctl restart docker

        image.png

        • 清空所有運行的容器
        docker rm $(sudo docker ps -a -q)

        image.png

        • 加入 jar 包端口 8012
        docker run -d --name jenkins -p 8040:8080 -p 8012:8012 -p 50000:50000 -v /data/jenkins_home:/var/jenkins_home jenkins/jenkins:2.222.3-centos
        • 刷新Jenkins

        image.png

        • 再次構建服務
        • 查看控制臺輸出

        image.png

        image.png

        • java -jar 屬于 前臺啟動方式導致一直在啟動中,控制臺一直轉圈

        image.png

        image.png

        • 修改為后臺啟動

        java -jar $JAR_NAME.jar 替換為 BUILD_ID=dontKillMe nohup java -jar $JAR_NAME.jar &
        image.png

        • 刪除剛剛啟動的服務,重新啟動

        image.png

        image.png

        查看原文

        贊 0 收藏 0 評論 0

        isWulongbo 發布了文章 · 2月24日

        Zuul管理整個微服務Swagger文檔

        思路

        每個微服務引入各自的swagger文檔,zuul做統一整合。

        模塊

        • 父工程 springcloud-parent 引入 swagger-spring-boot-starter 依賴:
        <!--swagger-spring-boot-->
        <dependency>
         <groupId>com.spring4all</groupId>
         <artifactId>swagger-spring-boot-starter</artifactId>
         <version>1.7.0.RELEASE</version>
        </dependency>

        注意:這里版本必須為1.7,使用1.9會有沖突
        image.png

        • 會員模塊 springcloud-api-member-service-impl 掃包
        swagger:
          base-package: com.baba.api.service.impl

        image.png

        MemberServiceImpl 中引入 swagger 相關注解,正常來說這部分應該寫入Controller中,并且最好用PostMapping或者GetMapping注解,不然每個接口會出現多個。這里只是演示:

        @ApiOperation("獲取會員相關信息")
        @ApiImplicitParam(name = "name",value = "用戶信息參數",required = true,dataType = "String")
        @RequestMapping("/getMember")
        public UserEntity getMember(@RequestParam("name") String name) {
            UserEntity userEntity = new UserEntity();
         userEntity.setName(name);
         userEntity.setPassword("123456");
         return userEntity;
        }

        image.png

        啟動類 AppMember 加入 @EnableSwagger2Doc
        image.png

        • 訂單模塊 springcloud-api-order-service-impl 掃包
        swagger:
          base-package: com.baba.api

        image.png

        OrderServiceImpl中引入 swagger 相關注解

        // 訂單服務接口
        @Override
        @ApiOperation("獲取訂單相關信息")
        @RequestMapping("/getOrderInfo")
        public String getOrderInfo() {
            System.out.println("getOrderInfo-->線程池名稱:" + Thread.currentThread().getName());
         return "訂單服務接口調用成功!";
        }

        ![上傳中...]()
        image.png

        啟動類 AppOrder 加入 @EnableSwagger2Doc
        image.png

        • 網關 gateway 中同樣引入 swagger-spring-boot-starter依賴
        <!--swagger-spring-boot-->
        <dependency>
         <groupId>com.spring4all</groupId>
         <artifactId>swagger-spring-boot-starter</artifactId>
         <version>1.7.0.RELEASE</version>
        </dependency>

        image.png
        注意:我這里還引入的 jaxb-api 依賴解決如下報錯,這個和jdk版本有關系,我這里還需要引入以下依賴

        Error creating bean with name 'xmlModelPlugin': Lookup method resolution failed;
        <dependency>
         <groupId>javax.xml.bind</groupId>
         <artifactId>jaxb-api</artifactId>
         <version>2.3.0</version>
        </dependency>

        TokenFilter 攔截器暫時注釋掉:
        image.png

        啟動類 AppGateway 中 添加文檔來源 并注入 @EnableSwagger2Doc 注解

        package com.baba.wlb;
        import com.spring4all.swagger.EnableSwagger2Doc;
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.boot.context.properties.ConfigurationProperties;
        import org.springframework.cloud.context.config.annotation.RefreshScope;
        import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
        import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
        import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
        import org.springframework.context.annotation.Primary;
        import org.springframework.stereotype.Component;
        import springfox.documentation.swagger.web.SwaggerResource;
        import springfox.documentation.swagger.web.SwaggerResourcesProvider;
        import java.util.ArrayList;
        import java.util.List;
        /**
         * @Author wulongbo
         * @Date 2021/1/28 11:52
         * @Version 1.0
         */@SpringBootApplication
        @EnableEurekaClient
        @EnableZuulProxy
        @EnableSwagger2Doc
        public class AppGateway {
            //@EnableZuulProxy 開啟網關代理
         public static void main(String[] args) {
                SpringApplication.run(AppGateway.class, args);
         }
            // zuul配置能夠使用config實現實時更新
         @RefreshScope
         @ConfigurationProperties("zuul")
            public ZuulProperties zuulProperties(){
                return new ZuulProperties();
         }
            // 添加文檔來源
         @Component
         @Primary class DocumentationConfig implements SwaggerResourcesProvider{
                @Override
         public List<SwaggerResource> get() {
                    List resource = new ArrayList();
         resource.add(swaggerResource("app-member","/api-member/v2/api-docs","2.0"));
         resource.add(swaggerResource("app-order","/api-order/v2/api-docs","2.0"));
         return resource;
         }
                private SwaggerResource swaggerResource(String name,String location,String version){
                    SwaggerResource swaggerResource=new SwaggerResource();
         swaggerResource.setName(name);
         swaggerResource.setLocation(location);
         swaggerResource.setSwaggerVersion(version);
         return swaggerResource;
         }
            }
        }

        image.png

        啟動

        依次啟動,Eureka server(集群[8100,9100]),config server,member服務,order服務,gateway(集群[81,82]),以及nginx(80)。
        image.png

        啟動成功后使用nginx做服務轉發訪問 http://localhost/swagger-ui.html
        image.png
        切換服務名稱:
        image.png

        至此 Zuul網關就管理到了整個微服務Swagger文檔

        查看原文

        贊 0 收藏 0 評論 0

        isWulongbo 發布了文章 · 2月24日

        Nginx+Zuul實現網關集群

        Nginx

        下載Nginx

        下載nginx,這里作者選用的是 nginx/Windows-1.16.1版本。
        解壓后如下:
        image.png

        Nginx常用命令

        • 啟動命令:start nginx
        • 停止命令:nginx.exe -s stop 或 nginx.exe -s quit
        • 查看Nginx版本:nginx -v

        Nginx啟動

        這里我們選擇cmd啟動,打開cmd,切換到nginx目錄
        image.png
        為了確保nginx的正確運行,我們先不要修改nginx.conf文件,直接使用命令啟動,看是否能正常訪問:localhost:80。

        項目調整

        • TokenFilter 中把端口號打印出來
        @Value("${server.port}")
        private String serverPort;

        image.png

        Zuul網關

        項目啟動順序

        1. 啟動 eureka-server服務(EurekaServer)
        2. 啟動 config-server服務(cloud config分布式配置中心--gitte)
        3. 啟動 app-member服務(會員服務)
        4. 啟動 app-order服務(訂單服務)
        5. cmd啟動 zuul 81網關
        6. idea啟動 zuul 82網關

        項目啟動后如下:
        image.png

        這里只對zuul網關集群服務做詳細介紹。

        cmd啟動 zuul 81網關

        • 找到jar包路徑

        image.png

        • cmd 切換到target目錄,執行 java -jar xxx.jar 命令

        image.png

        idea 啟動 zuul 82網關

        注:我這里啟了83的網關。

        • 修改 zuul api網關端口為82(83)

        image.png

        • idea啟動 AppGateway
        • 查看 eureka server 服務注冊列表

        image.png

        修改Nginx配置文件

        • 打開 nginx.conf 文件

        image.png

        • 添加上游服務器
             #### 上游服務器 集群 默認輪詢機制
            upstream backServer{
                server localhost:81;
                server localhost:83;
            }
        
            server {
                listen       80;
                server_name  localhost;
        
                #charset koi8-r;
        
                #access_log  logs/host.access.log  main;
        
                location / {
        
                    #root   html;
                    #index  index.html index.htm;
                    #### 指定上游服務器 負載均衡服務器
                    proxy_pass http://backServer;
                    index  index.html;
                }
        
                #error_page  404              /404.html;
        
                # redirect server error pages to the static page /50x.html
                #
                error_page   500 502 503 504  /50x.html;
                location = /50x.html {
                    root   html;
                }
        
                # proxy the PHP scripts to Apache listening on 127.0.0.1:80
                #
                #location ~ \.php$ {
                #    proxy_pass   http://127.0.0.1;
                #}
        
                # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
                #
                #location ~ \.php$ {
                #    root           html;
                #    fastcgi_pass   127.0.0.1:9000;
                #    fastcgi_index  index.php;
                #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
                #    include        fastcgi_params;
                #}
        
                # deny access to .htaccess files, if Apache's document root
                # concurs with nginx's one
                #
                #location ~ /\.ht {
                #    deny  all;
                #}
            }

        image.png
        可以看到 8183 的網關輪詢訪問
        image.png
        image.png

        證明網關實現了集群!

        查看原文

        贊 0 收藏 0 評論 0

        isWulongbo 發布了文章 · 2月20日

        EMQ入門使用

        項目目錄結構

        image.png

        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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
         <modelVersion>4.0.0</modelVersion>
         <groupId>com.shining</groupId>
         <artifactId>shinelinker-server-sdk</artifactId>
         <version>final</version>
         <dependencies> <!-- https://mvnrepository.com/artifact/org.eclipse.paho/org.eclipse.paho.client.mqttv3 -->
         <dependency>
         <groupId>org.eclipse.paho</groupId>
         <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
         <version>1.2.1</version>
         </dependency>
         <dependency> <groupId>cn.hutool</groupId>
         <artifactId>hutool-all</artifactId>
         <version>4.5.9</version>
         </dependency>
         <dependency> <groupId>org.slf4j</groupId>
         <artifactId>slf4j-log4j12</artifactId>
         <version>1.7.25</version>
         </dependency>
         <!-- fastjson -->
         <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>fastjson</artifactId>
         <version>1.2.58</version>
         </dependency>
         <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
         <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>druid-spring-boot-starter</artifactId>
         <version>1.1.23</version>
         </dependency>
         <!-- 引入阿里數據庫連接池 -->
         <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>druid</artifactId>
         <version>1.2.1</version>
         </dependency>
         <!-- mysql驅動 -->
         <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>8.0.12</version>
         </dependency> </dependencies></project>
        ImeiBean
        package com.shining.serversdk.bean;
        /**
         * @Author wulongbo
         * @Date 2021/2/20 10:05
         * @Version 1.0
         */
        public class ImeiBean {
            private String imei;
         public String getImei() {
                return imei;
         }
            public void setImei(String imei) {
                this.imei = imei;
         }
        }
        PublishBean
        package com.shining.serversdk.bean;
        import cn.hutool.json.JSONObject;
        /**
         * 發布的消息封裝
         */
        public class PublishBean {
            private String topic;
         private boolean mutable = true;
         private JSONObject payload;
         private int qos = 2;
         private boolean retained = false;
         private boolean dup = false;
         public boolean isMutable() {
                return mutable;
         }
            public void setMutable(boolean mutable) {
                this.mutable = mutable;
         }
            public JSONObject getPayload() {
                return payload;
         }
            public void setPayload(JSONObject payload) {
                this.payload = payload;
         }
            public int getQos() {
                return qos;
         }
            public void setQos(int qos) {
                this.qos = qos;
         }
            public boolean isRetained() {
                return retained;
         }
            public void setRetained(boolean retained) {
                this.retained = retained;
         }
            public boolean isDup() {
                return dup;
         }
            public void setDup(boolean dup) {
                this.dup = dup;
         }
            public String getTopic() {
                return topic;
         }
            public void setTopic(String topic) {
                this.topic = topic;
         }
        }
        DBConn
        package com.shining.serversdk.db;
        import java.sql.*;
        /**
         * @Author wulongbo
         * @Date 2021/2/20 10:03
         * @Version 1.0
         */public class DBConn {
            private static final String JDBCDriver = "com.mysql.cj.jdbc.Driver"; //mysql驅動
         private static final String url = "jdbc:mysql://39.102.56.91:3306/mybatis_plus";
         private static final String username = "root"; //數據庫用戶名
         private static final String password = "babaAdmin"; //數據庫密碼
         private static final Connection conn = null;
         /**
         * 連接數據庫
         * @return
         */
         public static Connection conn() {
                Connection conn = null;
         try {
                    Class.forName(JDBCDriver); //加載數據庫驅動
         try {
                        conn = DriverManager.getConnection(url, username, password); //連接數據庫
         } catch (SQLException e) {
                        e.printStackTrace();
         }
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
         }
                return conn;
         }
            /**
         * 關閉數據庫鏈接
         * @return
         */
         public static void close() {
                if(conn != null) {
                    try {
                        conn.close(); //關閉數據庫鏈接
         } catch (SQLException e) {
                        e.printStackTrace();
         }
                }
            }
        }
        DBUtil
        package com.shining.serversdk.db;
        import com.shining.serversdk.bean.ImeiBean;
        import java.sql.*;
        /**
         * @Author wulongbo
         * @Date 2021/2/20 10:04
         * @Version 1.0
         */public class DBUtil {
            private static Connection conn = null;
         private static PreparedStatement ps = null;
         private static ResultSet rs = null;
         private static final CallableStatement cs = null;
         /**
         * Insert方法封裝
         *
         * @param imeiBean 傳入參數
         */
         public static void Insert(ImeiBean imeiBean) {
                conn = DBConn.conn(); //調用 DBconnection 類的 conn() 方法連接數據庫
         String sql = "INSERT INTO student01 (sno,sname,dname,ssex,cno,mark,type) VALUES(?,?,?,?,?,?,?)"; //插入sql語句
         try {
                    ps = conn.prepareStatement(sql);
         /**
         * 調用實體imeiBean類,獲取需要插入的各個字段的值
         * 注意參數占位的位置
         * 通過set方法設置參數的位置
         * 通過get方法取參數的值
         */
         ps.setString(1, imeiBean.getImei());
         ps.executeUpdate(); //執行sql語句
         System.out.println("插入成功(* ̄︶ ̄)");
         } catch (SQLException e) {
                    e.printStackTrace();
         } finally {
                    DBConn.close();
         }
            }
        }
        MessageHandler
        package com.shining.serversdk.handler;
        import cn.hutool.json.JSONObject;
        import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
        import org.eclipse.paho.client.mqttv3.MqttCallback;
        import org.eclipse.paho.client.mqttv3.MqttMessage;
        /**
         * 消息處理器
         */
        public abstract class MessageHandler implements MqttCallback {
            /**
         * 異常處理
         *
         * @param throwable
         */
         public void connectionLost(Throwable throwable) {
                throwable.printStackTrace();
         onError(throwable);
         }
            /**
         * @param topic mqttTopic
         * @param mqttMessage Message
         * @throws Exception
         */ public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
                JSONObject jsonObject = new JSONObject();
         jsonObject.put("topic", topic);
         jsonObject.put("payload", new String(mqttMessage.getPayload(), "UTF-8"));
         jsonObject.put("retain", mqttMessage.isRetained());
         jsonObject.put("dup", mqttMessage.isDuplicate());
         jsonObject.put("messageId", mqttMessage.getId());
         messageArrived(jsonObject);
         }
            /**
         * 后續步驟
         *
         * @param iMqttDeliveryToken MessageID管理類
         */
         public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
                onComplete(iMqttDeliveryToken);
         }
            /**
         * 消息到達封裝JSON
         */ public abstract void messageArrived(JSONObject receivedMessage);
         /**
         * 出錯處理
         */
         public abstract void onError(Throwable throwable);
         /**
         * */ public abstract void onComplete(IMqttDeliveryToken iMqttDeliveryToken);
         /**
         * */ public abstract void onConnected();
        }
        PublishHandler
        package com.shining.serversdk.handler;
        public abstract class PublishHandler {
            public abstract void onSuccess();
         public abstract void onException(Exception e);
        }
        SubscribeHandler
        package com.shining.serversdk.handler;
        /**
         * 訂閱消息處理器
         * @author wwhai
         * @date 2019/7/31 20:21
         * @email:751957846@qq.com 瞅啥瞅?代碼拿過來我看看有沒有BUG。
         */
        public abstract class SubscribeHandler {
            public abstract void onSuccess(String topic,int qos);
         public abstract void onError(Exception e);
        }
        IServerMqttClient
        package com.shining.serversdk.sdkcore;
        import cn.hutool.json.JSONObject;
        import com.shining.serversdk.bean.PublishBean;
        import com.shining.serversdk.handler.PublishHandler;
        import com.shining.serversdk.handler.SubscribeHandler;
        import org.eclipse.paho.client.mqttv3.MqttMessage;
        /**
         * @author wwhai
         * 服務器端的SDK
         */public interface IServerMqttClient {
            /**
         * @param topic
         * @param qos
         * @return
         */
         boolean subscribe(String topic, int qos, SubscribeHandler subscribeHandler);
         /**
         * @param topic
         * @return
         */
         boolean unSubscribe(String topic);
         /**
         * @param topic
         * @param message
         * @return
         */
         boolean publish(String topic, MqttMessage message, PublishHandler publishHandler);
         /**
         * @param topic
         * @param message
         * @return
         */
         boolean publishJson(String topic, JSONObject message, PublishHandler publishHandler);
         /**
         * @param topic
         * @param bytes
         * @return
         */
         boolean publishHex(String topic, byte[] bytes, PublishHandler publishHandler);
         /**
         * publish */ boolean publish(PublishBean publishBean, PublishHandler publishHandler);
        }
        ServerMqttClient
        package com.shining.serversdk.sdkcore;
        import cn.hutool.json.JSONObject;
        import com.shining.serversdk.bean.PublishBean;
        import com.shining.serversdk.handler.MessageHandler;
        import com.shining.serversdk.handler.PublishHandler;
        import com.shining.serversdk.handler.SubscribeHandler;
        import org.eclipse.paho.client.mqttv3.*;
        import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
        public final class ServerMqttClient implements IServerMqttClient {
            private boolean isConnected;
         private String host;
         private int port;
         private MqttClient client;
         private String clientId;
         private String userName;
         private String passWord;
         /**
         * @param host
         * @param port
         * @param clientId
         * @param username
         * @param password
         */
         public ServerMqttClient(String host, int port, String clientId, String username, String password) {
                this.host = host;
         this.port = port;
         this.userName = username;
         this.passWord = password;
         this.clientId = clientId;
         }
            public boolean connect(MessageHandler messageHandler) {
                try {
                    client = new MqttClient("tcp://" + host + ":" + port, clientId, new MemoryPersistence());
         MqttConnectOptions options = new MqttConnectOptions();
         options.setCleanSession(false);
         options.setUserName(userName);
         options.setPassword(passWord.toCharArray());
         // 設置超時時間
         options.setConnectionTimeout(10);
         // 設置會話心跳時間
         options.setKeepAliveInterval(20);
         client.setCallback(messageHandler);
         client.connect(options);
         isConnected = true;
         messageHandler.onConnected();
         return true;
         } catch (Exception e) {
                    e.printStackTrace();
         isConnected = false;
         return false; }
            }
            /**
         * 訂閱
         *
         * @param topic
         * @param qos
         * @param subscribeHandler
         * @return
         */
         public boolean subscribe(String topic, int qos, SubscribeHandler subscribeHandler) {
                try {
                    client.subscribe(topic, qos);
         subscribeHandler.onSuccess(topic, qos);
         return true; } catch (MqttException e) {
                    e.printStackTrace();
         subscribeHandler.onError(e);
         return false; }
            }
            /**
         * 取消訂閱
         *
         * @param topic
         * @return
         */
         public boolean unSubscribe(String topic) {
                try {
                    client.unsubscribe(topic);
         return true; } catch (MqttException e) {
                    e.printStackTrace();
         return false; }
            }
            /**
         * 發布
         *
         * @param topic
         * @param message
         * @return
         */
         public boolean publish(String topic, MqttMessage message, PublishHandler publishHandler) {
                try {
                    client.publish(topic, message);
         publishHandler.onSuccess();
         return true; } catch (MqttException e) {
                    e.printStackTrace();
         publishHandler.onException(e);
         return false; }
            }
            /**
         * 發布JSON
         * @param topic
         * @param message
         * @param publishHandler
         * @return
         */
         public boolean publishJson(String topic, JSONObject message, PublishHandler publishHandler) {
                MqttMessage mqttMessage = new MqttMessage();
         mqttMessage.setPayload(message.toJSONString(1).getBytes());
         return this.publish(topic, mqttMessage, publishHandler);
         }
            /**
         * 發布16進制
         * @param topic
         * @param bytes
         * @param publishHandler
         * @return
         */
         public boolean publishHex(String topic, byte[] bytes, PublishHandler publishHandler) {
                MqttMessage mqttMessage = new MqttMessage();
         mqttMessage.setPayload(bytes);
         return this.publish(topic, mqttMessage, publishHandler);
         }
            /**
         * 發布消息
         * @param publishBean
         * @param publishHandler
         * @return
         */
         public boolean publish(PublishBean publishBean, PublishHandler publishHandler) {
                MqttMessage mqttMessage = new MqttMessage();
         mqttMessage.setQos(publishBean.getQos());
         mqttMessage.setRetained(publishBean.isRetained());
         mqttMessage.setPayload(publishBean.getPayload().toString().getBytes());
         try {
                    client.publish(publishBean.getTopic(), mqttMessage);
         publishHandler.onSuccess();
         return true; } catch (MqttException e) {
                    e.printStackTrace();
         publishHandler.onException(e);
         return false; }
            }
            /**
         * 是否在線
         * @return
         */
         public boolean isConnected() {
                return isConnected;
         }
        }
        Main啟動類
        package com.shining;
        import cn.hutool.json.JSONObject;
        import com.shining.serversdk.bean.ImeiBean;
        import com.shining.serversdk.db.DBUtil;
        import com.shining.serversdk.handler.MessageHandler;
        import com.shining.serversdk.handler.PublishHandler;
        import com.shining.serversdk.handler.SubscribeHandler;
        import com.shining.serversdk.sdkcore.ServerMqttClient;
        import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
        import org.eclipse.paho.client.mqttv3.MqttMessage;
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        public class Main {
            public static Logger logger = LoggerFactory.getLogger(Main.class);
         private static ServerMqttClient serverMqttClient;
         public static void main(String[] args) {
                serverMqttClient = new ServerMqttClient("39.102.56.91",
         1883,
         "JAVA-EMQ",
         "wulongbo",
         "study");
         serverMqttClient.connect(new MessageHandler() {
                    public void messageArrived(JSONObject receivedMessage) {
                        logger.info("消息{}到達", receivedMessage.toString());
         com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSON.parseObject(receivedMessage.toString());
         String code = jsonObject.getString("code");
         if (code != null && code.equals("3002")) {
                            String imei = jsonObject.getString("imei");
         /**
         * 下面為手動連接數據庫
         */
         try {
                                ImeiBean imeiBean = new ImeiBean();
         imeiBean.setImei(imei);
         DBUtil.Insert(imeiBean);
         } catch (Exception e) {
                                e.printStackTrace();
         }
                        }
                    }
                    public void onError(Throwable throwable) {
                    }
                    public void onComplete(IMqttDeliveryToken iMqttDeliveryToken) {
                    }
                    public void onConnected() {
                    }
                });
         /**
         * 判斷是否在線
         */
         if (serverMqttClient.isConnected()) {
                    /**
         * 訂閱
         */
         serverMqttClient.subscribe("study/java/emq", 2, new SubscribeHandler() {
                        @Override
         public void onSuccess(String topic, int qos) {
                            logger.info("主題{}發布成功!", topic);
         }
                        @Override
         public void onError(Exception e) {
                        }
                    });
         /**
         * 發布 Message
         */ MqttMessage mqttMessage = new MqttMessage();
         mqttMessage.setPayload(new byte[]{70, 85, 67, 75});
         serverMqttClient.publish("publish/test/topic", new MqttMessage(), new PublishHandler() {
                        @Override
         public void onSuccess() {
                            logger.info("主題發布Message成功!");
         }
                        @Override
         public void onException(Exception e) {
                        }
                    });
         /**
         * 發布JSON
         */
         JSONObject jsonObject = new JSONObject();
         jsonObject.put("action", "1");
         jsonObject.put("msgid", System.currentTimeMillis());
         jsonObject.put("type", "1");
         jsonObject.put("price", "1");
         serverMqttClient.publishJson("test", jsonObject, new PublishHandler() {
                        @Override
         public void onSuccess() {
                            logger.info("主題發布JSON成功!");
         //入庫
         }
                        @Override
         public void onException(Exception e) {
                            //
         }
                    });
         /**
         * 發布Hex
         */ serverMqttClient.publishHex("test", new byte[]{97, 98, 99, 100}, new PublishHandler() {
                        @Override
         public void onSuccess() {
                        }
                        @Override
         public void onException(Exception e) {
                        }
                    });
         /**
         * 使用封裝好的Pub Bean
         *///            PublishBean publishBean = new PublishBean();
        //            publishBean.setTopic("test");
        //            publishBean.setPayload(jsonObject);
        //            publishBean.setDup(true);
        //            publishBean.setRetained(true);
        //            publishBean.setMutable(true);
        //
        //            serverMqttClient.publish(publishBean, new PublishHandler() {
        //                @Override
        //                public void onSuccess() {
        //
        //                }
        //
        //                @Override
        //                public void onException(Exception e) {
        //
        //                }
        //            });
         } else {
                    System.out.println("連接失敗");
         }
            }
            public static void send() {
                for (int i = 0; i < 10; i++) {
                    JSONObject jsonObject = new JSONObject();
         jsonObject.put("action", "1");
         jsonObject.put("msgid", System.currentTimeMillis());
         jsonObject.put("type", "1");
         jsonObject.put("price", "1");
         send2(jsonObject);
         }
            }
            private static void send2(JSONObject jsonObject) {
                serverMqttClient.publishJson("test", jsonObject, new PublishHandler() {
                    @Override
         public void onSuccess() {
                        //入庫
         }
                    @Override
         public void onException(Exception e) {
                        // send2
         }
                });
         }
        }
        查看原文

        贊 0 收藏 0 評論 0

        isWulongbo 發布了文章 · 1月28日

        動態Zuul網關路由轉發

        springcloud-zuul-gateway

        pom文件新增依賴:

        <!--SpringCloud 整合 config-client--><dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-config-client</artifactId>
        </dependency>
        <!--actuator監控中心-->
        <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        image.png

        修改application.yml配置文件:

        ## api網關端口號
        server:
          port: 80
        ## 服務注冊名稱
        spring:
          application:
            name: server-zuul
          cloud:
            config:
              #### 讀取版本環境
         profile: dev
              discovery:
                #### config server 服務注冊別名
         service-id: config-server
                #### 開啟讀取權限
         enabled: true
        eureka:
          client:
            service-url:
              ##當前服務注冊到Eureka服務地址
         defaultZone: http://localhost:8100/eureka,http://localhost:9100/eureka
            register-with-eureka: true
         ## 需要檢索服務信息
         fetch-registry: true
        #### 配置動態
        #zuul:
        #  routes:
        #    ## 表示定義轉發服務規則
        #    api-a:
        #      ### 當客戶端發送請求http://127.0.0.1:80/api-member開頭的,都會轉發到會員服務
        #      path: /api-member/**
        #      ### 會員服務別名 zuul默認整合ribbon,自動實現輪詢效果
        #      serviceId: app-member
        #    api-b:
        #      ### 當客戶端發送請求http://127.0.0.1:80/api-order開頭的,都會轉發到訂單服務
        #      path: /api-order/**
        #      ### 訂單服務別名 zuul默認整合ribbon,自動實現輪詢效果
        #      serviceId: app-order
        ####開啟所有端點
        management:
          endpoints:
            web:
              exposure:
                include: "*"

        注釋掉的部分,新增yml文件到Getee上
        image.png
        image.png

        AppGateway啟動類新增zuul配置

        package com.baba.wlb;
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.boot.context.properties.ConfigurationProperties;
        import org.springframework.cloud.context.config.annotation.RefreshScope;
        import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
        import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
        import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
        /**
         * @Author wulongbo
         * @Date 2021/1/28 11:52
         * @Version 1.0
         */@SpringBootApplication
        @EnableEurekaClient
        @EnableZuulProxy
        public class AppGateway {
            //@EnableZuulProxy 開啟網關代理
         public static void main(String[] args) {
                SpringApplication.run(AppGateway.class, args);
         }
            // zuul配置能夠使用config實現實施更新
         @RefreshScope
         @ConfigurationProperties("zuul")
            public ZuulProperties zuulProperties(){
                return new ZuulProperties();
         }
        }

        image.png

        啟動項目

        依次啟動Eureka Server、Config Server、Zuul網關gateway,以及Member 或者 Order服務
        image.png

        Config Server服務

        分布式配置中心 config server驗證gitee上的配置文件能夠正確讀取,訪問:http://localhost:8888/server-zuul-dev.yml
        image.png

        網關訪問

        zuul網關訪問:http://localhost/api-member/getMember?name=iswulongbo&userToken=cloud
        image.png
        驗證動態讀取到了gitee上的配置文件,要動態修改或者動態新增服務到zuul網關,只需在gitee的配置文件中添加完后手動調用接口刷新或者通過集成bus消息總線就OK!這里不再說明。

        查看原文

        贊 0 收藏 0 評論 0

        isWulongbo 發布了文章 · 1月28日

        Zuul網關ZuulFilter攔截器

        前言

        該博客續寫于 SpringCloud整合Zuul網關,使用ZuulFilter攔截器來攔截接口請求。

        ZuulFilter

        TokenFilter:

        package com.baba.wlb.filter;
        import com.netflix.zuul.ZuulFilter;
        import com.netflix.zuul.context.RequestContext;
        import com.netflix.zuul.exception.ZuulException;
        import org.apache.commons.lang.StringUtils;
        import org.springframework.stereotype.Component;
        import javax.servlet.http.HttpServletRequest;
        /**
         * @Author wulongbo
         * @Date 2021/1/28 14:19
         * @Version 1.0
         */
        // 網關過濾器
        @Component
        public class TokenFilter extends ZuulFilter {
            // 過濾器類型
         /**
         * pre表示在請求前執行
         *
         * @return
         */
         @Override
         public String filterType() {
                return "pre";
         }
            // 過濾器執行順序,當一個請求在同一個階段存在多個過濾器的時候,過個過濾器執行順序
         @Override
         public int filterOrder() {
                return 0;
         }
            // 判斷過濾器是否生效
         @Override
         public boolean shouldFilter() {
                return true;
         }
            // 編寫過濾器攔截業務邏輯代碼
         @Override
         public Object run() throws ZuulException {
                // 案例:攔截所有的服務接口,判斷服務接口上是否有傳遞userToken
         // 1.獲取上下文
         RequestContext currentContext = RequestContext.getCurrentContext();
         // 2.獲取Request對象
         HttpServletRequest request = currentContext.getRequest();
         // 3.獲取token 的時候從請求頭中獲取
        //        String tenantId = request.getHeader("tenantId");
         String userToken = request.getParameter("userToken");
         if (StringUtils.isBlank(userToken)) {
                    // 不會繼續執行,不會去調用服務接口,網關服務直接響應給客戶端
         currentContext.setSendZuulResponse(false);
         currentContext.setResponseBody("userToken is null");
         currentContext.setResponseStatusCode(401);
         }
                // 正常執行,調用其他服務接口
         return null;
         }
        }

        image.png
        重啟網關,后訪問:http://localhost/api-order/getOrderByMember?name=iswulongbo
        image.png
        帶上userToken后:http://localhost/api-order/getOrderByMember?name=iswulongbo&userToken=aapid
        image.png
        訪問成功!

        查看原文

        贊 0 收藏 0 評論 0

        isWulongbo 發布了文章 · 1月28日

        SpringCloud整合Zuul網關

        簡介

        網關的作用

        網關可以攔截客戶端所有請求,對該請求進行權限控制,負載均衡,日志管理,接口調用監控等。

        網關與過濾器的區別

        過濾器是攔截單個tomcat服務器進請求,網關是攔截整個微服務所有請求。

        網關和Nginx的區別

        1. 相同點:Zuul和Nginx都可以實現負載均衡,反向代理,過濾請求,實現網關效果。
        2. 不同點:Nginx采用C語音編寫,Zuul采用java語音編寫。Zuul負載均衡實現:采用Ribbon+Eureka實現本地負載均衡。Nginx實現負載均衡:采用服務器端實現負載均衡。

        zuul網關實現反向代理

        新建springcloud-zuul-gateway 模塊

        • 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
         <parent> <artifactId>springcloud-parents</artifactId>
         <groupId>com.baba.wlb</groupId>
         <version>1.0-SNAPSHOT</version>
         </parent> <modelVersion>4.0.0</modelVersion>
         <artifactId>springcloud-zuul-gateway</artifactId>
         <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-dependencies</artifactId>
         <version>Finchley.M7</version>
         <type>pom</type>
         <scope>import</scope>
         </dependency> </dependencies> </dependencyManagement>
         <dependencies> <!--SpringCloud zuul 網關-->
         <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
         </dependency>
         <!--SpringCloud Eureka 客戶端-->
         <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
         </dependency> </dependencies>
         <!--注意:這里必須添加,否則各種依賴有問題-->
         <repositories>
         <repository> <id>spring-milestones</id>
         <name>Spring Milestones</name>
         <url>https://repo.spring.io/libs-milestone</url>
         <snapshots> <enabled>false</enabled>
         </snapshots> </repository> </repositories></project>
        • application.yml 配置文件
        ## api網關端口號
        server:
          port: 80
        ## 服務注冊名稱
        spring:
          application:
            name: server-zuul
        eureka:
          client:
            service-url:
              ##當前服務注冊到Eureka服務地址
         defaultZone: http://localhost:8100/eureka,http://localhost:9100/eureka
            register-with-eureka: true
         ## 需要檢索服務信息
         fetch-registry: true
        zuul:
          routes:
            ## 表示定義轉發服務規則
         api-a:
              ### 當客戶端發送請求http://127.0.0.1:80/api-member開頭的,都會轉發到會員服務
         path: /api-member/**
              ### 會員服務別名 zuul默認整合ribbon,自動實現輪詢效果
         serviceId: app-member
            api-b:
              ### 當客戶端發送請求http://127.0.0.1:80/api-order開頭的,都會轉發到訂單服務
         path: /api-order/**
              ### 訂單服務別名 zuul默認整合ribbon,自動實現輪詢效果
         serviceId: app-order
        • AppGateway 啟動類
        package com.baba.wlb;
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
        import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
        /**
         * @Author wulongbo
         * @Date 2021/1/28 11:52
         * @Version 1.0
         */@SpringBootApplication
        @EnableEurekaClient
        @EnableZuulProxy
        public class AppGateway {
            //@EnableZuulProxy 開啟網關代理
         public static void main(String[] args) {
                SpringApplication.run(AppGateway.class, args);
         }
        }

        啟動服務

        依次Eureka Server、Zuul網關、Member服務、Order服務
        訪問訂單接口:http://localhost:8200/getOrderByMember?name=11
        image.png
        再訪問網關:http://localhost/api-order/getOrderByMember?name=11
        image.png
        實現了反向代理!

        查看原文

        贊 0 收藏 0 評論 0

        認證與成就

        • 獲得 67 次點贊
        • 獲得 2 枚徽章 獲得 0 枚金徽章, 獲得 0 枚銀徽章, 獲得 2 枚銅徽章

        擅長技能
        編輯

        開源項目 & 著作
        編輯

        注冊于 2020-07-13
        個人主頁被 3.9k 人瀏覽

        一本到在线是免费观看_亚洲2020天天堂在线观看_国产欧美亚洲精品第一页_最好看的2018中文字幕