1. 程式人生 > 實用技巧 >flink 動態支援依賴jar包提交

flink 動態支援依賴jar包提交

info

我加入2084團隊的這些日子都幹了啥?

學習與實現code經歷

入團隊背景

  1. 大一下,因為疫情原因在家沒有上學,恰逢2084團隊招新,憑著對技術的熱愛和沒事閒著的心態,通過了覃輝學長的面試加入到團隊,由於我學的是Java,所以自然的幹起了後端。

JavaWeb

  1. 最開始寫了一個基於socket通訊的小demo,用的是純原生的JavaWeb,這個時期的程式碼很原始,業務邏輯都是自己手工做出的,也很像java程式碼。然後通過學長的指引和自己搜尋的資料,發現:都2020年了,沒有哪一個企業甚至是開發流程使用原生的JavaWeb,更多的是利用可以能夠敏捷開發的Framework,這些framework和工具都是可以幫助開發者快速實現功能的法寶利器,當然他們的底層還是javaWeb等協議封裝出來的。

MySQL

  1. javaweb之後就是MySQL,資料庫不得不說是一個非常重要的東西,業內開發最普遍的關係型資料庫工具是MySQL和Oracle,而這兩者MySQL佔比80%,學號mysql是進入後端的第一步,當然對於初學者,學一些基礎,能夠操作資料庫,把資料庫的東西拿出來,而對一些更為複雜的知識,如鎖,執行緒排程,索引的效能調優只是初步瞭解,短期學習也用不到。

Tomcat

  1. 然後初步學習了一些之後,學長髮布了做一個登入註冊的demo。6月份末7月份初,開始著手這個demo。我們都知道,最開始的javaweb服務大都是跑在Tomcat這個web容器中的,對於Tomcat來講,支援java原生的jsp程式碼,對於H5頁面支援不是那麼好,這時的疑慮也很大:為什麼市面上大多數網站好像都是h5?7月12日
    這個簡單的demo完成之後,發現在操作資料庫比較複雜,需要大量的JDBC程式碼,於是ORM框架學習跟進。

MyBatis+Maven

  1. 當時對於ORM的選擇Hibernate還是MyBatis,全自動Hibernate,半自動MyBatis。MyBatis對於資料庫的物件對映操作支援的很好,而且支援一些高階結果集對映和快取機制,7月15日開始學習mybatis,經過短暫的學習,mybatis初步瞭解,這是打通了mysql和java POJO類的隔閡,更加快速的與java實體類相互聯絡,對於原來的專案做了一個整合,使用Maven構建了pom依賴,就是匯入相關的jar包。

Spring

  1. MyBatis之後就是Spring,快速的企業開發需要spring支援。第一點是 對於一些物件不需要重複的new ,因為在一個專案中,考慮的不僅僅是速度,還有整體的效能,new 需要棧儲存名索引,堆的變數例項空間,而在一些程式中,我們使用的物件僅僅是一個,但是還是在不同的類中,new顯得沒那麼高的效能;第二點,對於快速的整合一些新東西,比如加日誌排錯,新加了個日誌啟動類,從service層到dao層,在每個類中都需要加入相關程式碼,這堆程式碼的整體協調性不好。Spring引入自動裝配注入DI,控制反轉IOC,面向切面AOP都很好的解決了這些問題。

SpringMVC

  1. Spring其實沒有對業務的整體邏輯造成什麼改變,只要引入jar包,任何程式都可以是spring的,spring只是改變了生產方式,接下來對於MVC三層架構使用的是SpringMVC,檢視層,模型層,控制層,在用原有的專案整合SpringMVC時也遇到了不少的BUG,尤其是MVC的配置檔案,這時的java程式碼已經有點不像java了,寫配置檔案甚至比業務程式碼還多,配置檔案繁瑣,spring還要尋找上下文context,各種層的配置檔案都得重寫,有時因為一個檔案,甚至一行配置寫不對,整體環境直接掛掉。

伺服器部署,專案上線

  1. 不過好在在踩了無數個坑之後,修復好了bug,專案可以釋出了,但是這時依然是傳統的Tomcat Web容器方式,我只好把寫過的HTML程式碼和一些java程式碼轉到jsp裡面去,這時的前端h5傳資料給後端是表格,後端給前端是jsp方式。7月19日阿里雲伺服器買到手,幸運的是6月14日後端剛成立時學了Git,然後花了幾天時間簡單學了Linux作業系統,這裡要說Linux比Windows更方便,親身體會。那麼把服務部署到雲端,還是tomcat的web容器。還有一點就是,因為windows本地的環境和雲上的環境不同,導致最開始上傳war包,找不到ip:/8080/login 這個服務,也是配置了好長時間才解決,找了好久才發現mvc的Context配置檔案和本地的不同。

SpringBoot微服務

  1. 在做好單體的服務之後,感覺SpringMVC這套流程太過於複雜,springBoot封裝了ssm把一切的配置全部寫進application.yaml 一切的jar包全部由maven-pom匯入,而且內嵌Tomact容器,我們只需要專注於業務程式碼就好了。而且微服務還有的好處就是,既可以做單體,又可以做分散式叢集,服務易於擴充套件和拆分,整體服務加一個註冊中心搞定。8月份開始SpringBoot,這時開始進行安卓端+PC端+後端聯調測試了,並開始前後端分離。那麼就需要寫介面文件,這個文件相當於手冊,所有開發人員都用這個手冊,並進行開發。

Swagger介面文件

  1. 直接把最開始的文件程式碼貼上
swagger: '2.0'
info:
  version: 1.0.0
  title: Web Login UI API
  description: >-
    A API that shows what Back-end do and grant invoking privileges to all 2084
    Team programmers.
schemes:
  - http
  - https
externalDocs:
  description: |
    **Complete** documentation describing how to use this API . 
  url: 'http://xiyuan.ren'
host: xiyuan.ren
basePath: /login
tags:
  - name: user
    description: Online user's information only has username and password.
  - name: register
    description: User's complete information.
  - name: file
    description: >-
      User's want to upload some files ,for example,Feedback Documents. Or other
      binary files .
paths:
  /users:
    get:
      tags:
        - user
      summary: Get all online users.
      description: Returns a list containing all users online .This list supports paging .
      produces:
        - application/json
      consumes:
        - application/json
      parameters:
        - $ref: '#/parameters/pageSize'
        - $ref: '#/parameters/pageNumber'
      responses:
        '200':
          description: Get all online users.
          schema:
            $ref: '#/definitions/Users'
          examples:
            application/json:
              items:
                - username: 2048團隊666
                  password: TEAM2048fly
                - username: '抗擊病毒,從你我做起'
                  password: DeafeatVirus666
                - ... and more ...
        '400':
          description: No user online.
        '500':
          $ref: '#/responses/Standard500ErrorResponse'
        default:
          $ref: '#/responses/DefaultErrorResponse'
  /user:
    post:
      tags:
        - user
      summary: Login
      description: Add a new user to the online user list .
      produces:
        - application/json
      consumes:
        - application/json
      parameters:
        - name: user
          in: body
          schema:
            $ref: '#/definitions/User'
      responses:
        '200':
          description: 'The user logins successfully,means binding its device.'
        '400':
          description: >-
            The user online failed,probably username doesn't exist or password
            is incorrect.
        '500':
          $ref: '#/responses/Standard500ErrorResponse'
        default:
          $ref: '#/responses/DefaultErrorResponse'
  '/user/{username}':
    get:
      tags:
        - user
      summary: Get a user by username.
      description: Returns a user via parameter username .
      produces:
        - application/json
      consumes:
        - application/json
      parameters:
        - $ref: '#/parameters/username'
      responses:
        '200':
          description: The user is founded.
          schema:
            $ref: '#/definitions/User'
        '400':
          $ref: '#/responses/UserDoesNotExistResponse'
        '500':
          $ref: '#/responses/Standard500ErrorResponse'
        default:
          $ref: '#/responses/DefaultErrorResponse'
  '/user/{username}{password}':
    delete:
      tags:
        - user
      summary: Logout
      description: 'Remove the user from online list,means unbinding its device.'
      produces:
        - application/json
      consumes:
        - application/json
      parameters:
        - $ref: '#/parameters/username'
        - $ref: '#/parameters/password'
      responses:
        '200':
          description: 'User Logout,unbinding.'
        '400':
          $ref: '#/responses/UserDoesNotExistResponse'
        '500':
          $ref: '#/responses/Standard500ErrorResponse'
        default:
          $ref: '#/responses/DefaultErrorResponse'
  /register:
    post:
      tags:
        - register
      summary: A new user to register.
      description: Add a new user to our service database.
      parameters:
        - name: register
          in: body
          schema:
            $ref: '#/definitions/Register'
      produces:
        - application/json
      consumes:
        - application/json
      responses:
        '200':
          description: Register successfully .
        '400':
          description: >-
            Probobly user's error ,for example the password and ensure password
            is not equals,please show a web popup to user instead of 400error
            we  will not permit the information convey to the back-end.
        '500':
          $ref: '#/responses/Standard500ErrorResponse'
        default:
          $ref: '#/responses/DefaultErrorResponse'
      security:
        - userAPIKEY: []
  /registers:
    get:
      tags:
        - register
      summary: Get all registers.
      description: Get all registered users.
      produces:
        - application/json
      consumes:
        - application/json
      responses:
        '200':
          description: Gets successfully .
          schema:
            $ref: '#/definitions/Registers'
          examples:
            application/json:
              items:
                - username: 2048團隊666
                  password: TEAM2048fly
                  ensurepassword: TEAM2048fly
                  email: [email protected]
                  sex: male
                  registerTime: ''
                  '': ''
                - ....: null
        '400':
          $ref: '#/responses/UserDoesNotExistResponse'
        '500':
          $ref: '#/responses/Standard500ErrorResponse'
        default:
          $ref: '#/responses/DefaultErrorResponse'
      security:
        - userAPIKEY: []
  '/register/{username}{password}':
    put:
      tags:
        - register
      summary: An user to update .
      description: update user's information from the database .
      parameters:
        - $ref: '#/parameters/username'
        - $ref: '#/parameters/password'
      produces:
        - application/json
      consumes:
        - application/json
      responses:
        '200':
          description: update user's information successfully .Database forever exists.
        '400':
          $ref: '#/responses/UserDoesNotExistResponse'
        '500':
          $ref: '#/responses/Standard500ErrorResponse'
        default:
          $ref: '#/responses/DefaultErrorResponse'
      security:
        - userAPIKEY: []
    delete:
      tags:
        - register
      summary: An user to destroy .
      description: >-
        Delete the user from the database,the user information will never occur
        in our server.
      produces:
        - application/json
      consumes:
        - application/json
      parameters:
        - $ref: '#/parameters/username'
        - $ref: '#/parameters/password'
      responses:
        '200':
          description: >-
            delete the user successfully and the user will never exist in our
            database forever .
        '400':
          description: User does not exist in our server.
        '500':
          $ref: '#/responses/Standard500ErrorResponse'
        default:
          $ref: '#/responses/DefaultErrorResponse'
      security:
        - userAPIKEY: []
  '/text/{username}':
    post:
      tags:
        - file
      summary: the text user's uploaded
      description: >-
        The feedback that the user write in a small box.We want the feedback
        restricted to 300 words per time.
      parameters:
        - $ref: '#/parameters/username'
        - name: Feedback text
          in: body
          description: User's feedback
          schema:
            type: string
            format: formData
      produces:
        - application/json
      consumes:
        - application/json
      responses:
        '200':
          description: Feedback is received successfuly.
        '400':
          description: Feedback is missing.
        '500':
          $ref: '#/responses/Standard500ErrorResponse'
        default:
          $ref: '#/responses/DefaultErrorResponse'
      security:
        - userAPIKEY: []
  '/image/{username}{password}{image}':
    post:
      tags:
        - file
      summary: the image icon user's uploaded
      description: the feedback that the user write in a small box.
      consumes:
        - application/json
      parameters:
        - $ref: '#/parameters/username'
        - $ref: '#/parameters/password'
        - name: image
          in: path
          required: true
          type: string
          format: file
      produces:
        - image/png
        - image/gif
        - image/jpeg
        - application/json
        - application/x-yaml
      responses:
        '200':
          description: image is received successfuly.
        '400':
          description: image is missing.
        '500':
          $ref: '#/responses/Standard500ErrorResponse'
        default:
          $ref: '#/responses/DefaultErrorResponse'
  '/image/{username}':
    get:
      tags:
        - file
      summary: Gets an user's image.
      consumes:
        - application/json
      parameters:
        - $ref: '#/parameters/username'
      produces:
        - image/png
        - image/gif
        - image/jpeg
        - application/json
        - application/x-yaml
      responses:
        '200':
          description: The user's image find successfully.
        '404':
          $ref: '#/responses/UserDoesNotExistResponse'
        '500':
          $ref: '#/responses/Standard500ErrorResponse'
        default:
          $ref: '#/responses/DefaultErrorResponse'
securityDefinitions:
  userbasic:
    type: basic
  userAPIKEY:
    name: userAPIKEY
    in: header
    type: apiKey
  userOauth2:
    type: oauth2
    flow: accessCode
    authorizationUrl: 'http://'
    tokenUrl: 'http://'
definitions:
  Register:
    required:
      - username
      - password
      - ensurePassword
      - phone
    properties:
      username:
        $ref: '#/parameters/username'
      password:
        $ref: '#/parameters/password'
      ensurePassword:
        type: string
        description: >-
          The ensure password must absolutely equals to the password, I wanna
          that if the ensurePassword not equals password ,an alertion will be
          occured in the web page{兩次密碼不一致!},while not to convey the error to the
          back-end.
      email:
        type: string
        description: To send emails.
      sex:
        type: string
        description: 'three options is best choice  male ,female or the keep secret'
      registerTime:
        type: string
        format: dateTime
        readOnly: true
        example: '2001-08-17T16:07:06Z'
      avatorBase64PNG:
        type: string
        format: byte
      phone:
        type: string
        description: To send Verification code.
  Registers:
    properties:
      items:
        type: array
        minItems: 0
        maxItems: 100
        uniqueItems: true
        items:
          $ref: '#/definitions/Register'
  User:
    required:
      - username
      - password
    properties:
      username:
        $ref: '#/parameters/username'
      password:
        $ref: '#/parameters/password'
  Users:
    properties:
      items:
        type: array
        minItems: 0
        maxItems: 100
        uniqueItems: true
        items:
          $ref: '#/definitions/User'
  Error:
    properties:
      code:
        type: string
        default: 500
      message:
        type: string
        default: ERROR
    description: The Error message can be DIY .
  OK:
    properties:
      message:
        type: string
        default: OK
    description: The OK message can also be DIY .
parameters:
  username:
    name: username
    in: path
    required: true
    description: >-
      The user's username .The username is the identification of every users.So
      it is a unique field.The string length must range 1-64,the Chinese
      character is also allowed,tell the user how to fill,when the username is
      not availiable please show the message in webPages {使用者名稱重複!}.
    type: string
  password:
    name: password
    in: path
    required: true
    pattern: '[a-zA-Z0-9]{8-64}'
    description: >-
      Please give the user description on how to fill the password.The string
      length must range 8-64,if less 8 tells user {可能不安全!}.And every letter must
      be a-z A-Z 0-9,other word is not avaliable.The user’s password is the key
      for the user to login and bind to the computer. After transform from
      webPage to the Server backend.The password will be encrypted by MD5, the
      letters are all unified into uppercase.
    type: string
    format: password
  pageSize:
    name: pageSize
    in: query
    description: Number of users returned
    type: integer
    minimum: 0
    exclusiveMinimum: true
    maximum: 100
    exclusiveMaximum: true
    default: 20
  pageNumber:
    name: pageNumber
    in: query
    description: pageNumber
    type: integer
    minimum: 0
    exclusiveMinimum: true
    maximum: 100
    exclusiveMaximum: true
    default: 20
responses:
  AlltheRequestCorrectResponse:
    description: >-
      No Errors and no warnings,all the things seem to be perfect.Always code
      {2**} to user.
    schema:
      $ref: '#/definitions/OK'
    examples:
      application/json:
        message: OK
  UserDoesNotExistResponse:
    description: >-
      User does not exist,I want the web page can give the message{user=null} 
      to the back-end.Always status code{4**} to user.
    schema:
      $ref: '#/definitions/Error'
    examples:
      application/json:
        code: '404'
        message: NotFound
  Standard500ErrorResponse:
    description: >-
      An unexpected error occured .This can be a nonsense error or a server
      error,please definate by yours.Always status code{5**} to user.
    schema:
      $ref: '#/definitions/Error'
    examples:
      application/json:
        code: '500'
        message: ServerError
  DefaultErrorResponse:
    description: >-
      Unknown error,The server knows none,the Web Pages knows none.Alway status
      code{963} or none.
    schema:
      $ref: '#/definitions/Error'
    examples:
      application/json:
        code: '963'
        message: UnknownError

這個介面文件寫完就不能修改了,所以要和其他端的人員商量好,這個開始我們沒有商量好,造成了一點麻煩。還有一點就是,我以為前後端開發是web前端和web後端,所以我這邊寫完上線就找那邊測試,但是搞烏龍了,安卓端是前端,web前端還是我們寫,於是在8月23日聯合測試介面之後,我用Bootstrap又寫了一下web前端,8月末優化了前端頁面與使用者體驗。

在最開始的時期文件需要寫,但Springboot階段文件用註解直接生成的,一些註解搞定了文件排布,文件和這些介面只對於開發者可見。

Web前端

  1. web前端基於Bootstrap響應式佈局和Semantic-UI圖示 訪問 http://121.41.229.179:8081 可以看到,並且可以註冊

比如登陸註冊服務的web端是javascript+jqueryAjax 進行快速響應來 優化使用者體驗。

比如:

SpringSecurity

  1. 這個網站集成了 使用者管理介面,前端頁面,swagger-ui開發者文件,安卓端及PC端相關介面,聯調過了可以使用,並且我還在內部設定了許可權管理,不同的人(開發者admin,普通使用者 normal,管理員master,付費使用者vip)能看到的內容和服務是不同的,這也方便了以後網站開發的維護。這些功能的實現基於SpringSecurity的建立,目前的註冊業務只有郵箱,因為個人原因(身份證到期,辦理較慢)沒有簡訊業務和域名配置,這些功能會在後續完善。

現在利用的security還是沒有找到OAuth2第三方鑑權和認證的解決方法,這個後續會整合進服務中。

學長讓我把可能的密碼md5加密,我想還是不用了,因為本身security就有一個加密的機制,在加一個會不會顯得畫蛇添足?這個後續可以商量....

Docker部署

  1. 由於容器技術的發展Docker部署成了開發者必備的技能,極大簡約開發部署上線環節,DevOps營運而生,Docker部署需要一定的知識,我也學了差不多半個月,好處是映象是疊加的,減少伺服器開銷,方便查閱日誌,容器互聯,資料掛載在磁碟分割槽,容器刪除資料不會丟失.........

現在後端的部署模式是整體服務用maven構建專案,springboot部署整個微服務(基本上是註解),配置檔案就一個application.yaml 然後Docker部署應用(構建build+Dockerfile+容器服務打通埠上線)

-----至此就是我加入2084團隊期間做的事情

未來與展望

短期目標

把目前的Oauth2,TOKEN做好,實現第三方登入,與MQTT南東平那邊互聯一下.

長期目標

身為2084團隊一員,肯定希望把服務做好,我對於服務地整體部署環節瞭解的還算可以,那麼接下來呢,我認為

微服務架構圖

但目前我覺得分散式註冊中心不可行,因為單體的目前沒做好,使用者也...,一上來就分散式也浪費

隨著時間的增長,個人技術棧是疊加的,考慮的問題也更復雜,但是,學長,我認為先做單體,然後再分散式,至於內網穿透NAT給點時間。