Forráskód Böngészése

fixed canal-admin vue

agapple 5 éve
szülő
commit
e376a129ed
36 módosított fájl, 140 hozzáadás és 100 törlés
  1. 6 0
      canal-admin/canal-admin-server/pom.xml
  2. 2 2
      canal-admin/canal-admin-server/src/main/resources/application.yml
  3. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/index.html
  4. 1 0
      canal-admin/canal-admin-server/src/main/resources/public/static/css/chunk-1ef583f0.ec3a43f5.css
  5. 0 1
      canal-admin/canal-admin-server/src/main/resources/public/static/css/chunk-555c32e2.9d3c5014.css
  6. 1 0
      canal-admin/canal-admin-server/src/main/resources/public/static/css/chunk-5560c396.b660603c.css
  7. 0 1
      canal-admin/canal-admin-server/src/main/resources/public/static/css/chunk-63c8061b.acff1abf.css
  8. 1 0
      canal-admin/canal-admin-server/src/main/resources/public/static/css/chunk-6f6d6145.bf63041a.css
  9. 0 1
      canal-admin/canal-admin-server/src/main/resources/public/static/css/chunk-7279d7fc.84a25dbe.css
  10. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/app.38307ef0.js
  11. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-101fc062.372a5ca5.js
  12. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-137eaf06.539d27c7.js
  13. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-137eaf06.867259ad.js
  14. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-1ef583f0.c799c803.js
  15. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-238a81e9.da844a27.js
  16. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-37c49cbf.92ebe0ae.js
  17. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-4f09fed2.d107437b.js
  18. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-555c32e2.6c39a877.js
  19. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-5560c396.5eb91155.js
  20. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-69386cf0.bdbe3f0c.js
  21. 1 1
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-6f6d6145.385d3c06.js
  22. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-7279d7fc.22670fea.js
  23. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-7ec889b7.192dc04c.js
  24. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-e1a839e4.3175ead5.js
  25. 0 0
      canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-e1a839e4.c870a02b.js
  26. 20 0
      canal-admin/canal-admin-server/src/test/java/com/alibaba/otter/canal/admin/jmx/JMXConnectionTest.java
  27. 14 14
      canal-admin/canal-admin-ui/src/router/index.js
  28. 23 23
      canal-admin/canal-admin-ui/src/views/canalServer/CanalInstance.vue
  29. 3 3
      canal-admin/canal-admin-ui/src/views/canalServer/CanalInstanceAdd.vue
  30. 1 1
      canal-admin/canal-admin-ui/src/views/canalServer/CanalInstanceUpdate.vue
  31. 1 1
      canal-admin/canal-admin-ui/src/views/canalServer/Config.vue
  32. 32 32
      canal-admin/canal-admin-ui/src/views/canalServer/NodeServer.vue
  33. 16 11
      client-adapter/common/src/main/java/com/alibaba/otter/canal/client/adapter/support/AbstractEtlService.java
  34. 3 3
      client-adapter/launcher/src/main/java/com/alibaba/otter/canal/adapter/launcher/loader/AbstractCanalAdapterWorker.java
  35. 10 6
      client-adapter/rdb/src/main/java/com/alibaba/otter/canal/client/adapter/rdb/RdbAdapter.java
  36. 5 0
      client-adapter/rdb/src/main/java/com/alibaba/otter/canal/client/adapter/rdb/service/RdbSyncService.java

+ 6 - 0
canal-admin/canal-admin-server/pom.xml

@@ -48,6 +48,12 @@
             <groupId>commons-lang</groupId>
             <artifactId>commons-lang</artifactId>
         </dependency>
+		<!-- junit -->
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
     </dependencies>
 
     <build>

+ 2 - 2
canal-admin/canal-admin-server/src/main/resources/application.yml

@@ -7,8 +7,8 @@ spring:
 
 spring.datasource:
     url: jdbc:mysql://127.0.0.1:3306/canal_manager?useUnicode=true&characterEncoding=UTF-8&useSSL=false
-    username: root
-    password: 121212
+    username: canal
+    password: canal
     driver-class-name: com.mysql.jdbc.Driver
     hikari:
       maximum-pool-size: 10

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/index.html


+ 1 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/css/chunk-1ef583f0.ec3a43f5.css

@@ -0,0 +1 @@
+.line[data-v-01afb045]{text-align:center}

+ 0 - 1
canal-admin/canal-admin-server/src/main/resources/public/static/css/chunk-555c32e2.9d3c5014.css

@@ -1 +0,0 @@
-.line[data-v-44b63e9d]{text-align:center}

+ 1 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/css/chunk-5560c396.b660603c.css

@@ -0,0 +1 @@
+.line[data-v-ae6e8604]{text-align:center}

+ 0 - 1
canal-admin/canal-admin-server/src/main/resources/public/static/css/chunk-63c8061b.acff1abf.css

@@ -1 +0,0 @@
-.line[data-v-5feb688e]{text-align:center}

+ 1 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/css/chunk-6f6d6145.bf63041a.css

@@ -0,0 +1 @@
+.line[data-v-250c9dcc]{text-align:center}

+ 0 - 1
canal-admin/canal-admin-server/src/main/resources/public/static/css/chunk-7279d7fc.84a25dbe.css

@@ -1 +0,0 @@
-.line[data-v-11496239]{text-align:center}

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/app.38307ef0.js


+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-101fc062.bc898027.js → canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-101fc062.372a5ca5.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-137eaf06.539d27c7.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-137eaf06.867259ad.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-1ef583f0.c799c803.js


+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-238a81e9.273bda76.js → canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-238a81e9.da844a27.js


+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-37c49cbf.64d26540.js → canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-37c49cbf.92ebe0ae.js


+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-4f09fed2.ff28d88d.js → canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-4f09fed2.d107437b.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-555c32e2.6c39a877.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-5560c396.5eb91155.js


+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-69386cf0.76d77f5c.js → canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-69386cf0.bdbe3f0c.js


+ 1 - 1
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-63c8061b.7ccc9231.js → canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-6f6d6145.385d3c06.js

@@ -1 +1 @@
-(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-63c8061b"],{"09a8":function(n,t,e){"use strict";e.r(t);var o=function(){var n=this,t=n.$createElement,e=n._self._c||t;return e("div",[e("el-form",{ref:"form",attrs:{model:n.form}},[e("div",{staticStyle:{"padding-left":"10px","padding-top":"20px"}},[e("el-form-item",[n._v("\n        "+n._s(n.form.name)+"    \n        "),e("el-button",{attrs:{type:"primary"},on:{click:n.onSubmit}},[n._v("修改")]),n._v(" "),e("el-button",{attrs:{type:"warning"},on:{click:n.onCancel}},[n._v("重置")])],1)],1),n._v(" "),e("editor",{attrs:{lang:"properties",theme:"chrome",width:"100%",height:800},on:{init:n.editorInit},model:{value:n.form.content,callback:function(t){n.$set(n.form,"content",t)},expression:"form.content"}})],1)],1)},a=[],i=(e("7f7f"),e("b775"));function r(){return Object(i["a"])({url:"/canal/config",method:"get"})}function c(n){return Object(i["a"])({url:"/canal/config",method:"put",data:n})}var f={components:{editor:e("7c9e")},data:function(){return{form:{id:null,name:"",content:""}}},created:function(){this.loadCanalConfig()},methods:{editorInit:function(){e("2099"),e("be9d"),e("2968"),e("e0e5"),e("bb36"),e("0329"),e("95b8"),e("6a21")},loadCanalConfig:function(){var n=this;r().then(function(t){var e=t.data;n.form.id=e.id,n.form.name=e.name,n.form.content=e.content})},onSubmit:function(){var n=this;this.$confirm("修改Canal主配置可能会导致Server重启,是否继续?","确定修改",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then(function(){c(n.form).then(function(t){"success"===t.data?(n.$message({message:"修改成功",type:"success"}),n.loadCanalConfig()):n.$message({message:"修改失败",type:"error"})})})},onCancel:function(){this.loadCanalConfig()}}},s=f,u=(e("a447"),e("2877")),l=Object(u["a"])(s,o,a,!1,null,"5feb688e",null);t["default"]=l.exports},"70a0":function(n,t,e){},a447:function(n,t,e){"use strict";var o=e("70a0"),a=e.n(o);a.a}}]);
+(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-6f6d6145"],{"09a8":function(n,t,e){"use strict";e.r(t);var o=function(){var n=this,t=n.$createElement,e=n._self._c||t;return e("div",[e("el-form",{ref:"form",attrs:{model:n.form}},[e("div",{staticStyle:{"padding-left":"10px","padding-top":"20px"}},[e("el-form-item",[n._v("\n        "+n._s(n.form.name)+"    \n        "),e("el-button",{attrs:{type:"primary"},on:{click:n.onSubmit}},[n._v("修改")]),n._v(" "),e("el-button",{attrs:{type:"warning"},on:{click:n.onCancel}},[n._v("重置")])],1)],1),n._v(" "),e("editor",{attrs:{lang:"properties",theme:"chrome",width:"100%",height:800},on:{init:n.editorInit},model:{value:n.form.content,callback:function(t){n.$set(n.form,"content",t)},expression:"form.content"}})],1)],1)},a=[],c=(e("7f7f"),e("b775"));function i(){return Object(c["a"])({url:"/canal/config",method:"get"})}function r(n){return Object(c["a"])({url:"/canal/config",method:"put",data:n})}var f={components:{editor:e("7c9e")},data:function(){return{form:{id:null,name:"",content:""}}},created:function(){this.loadCanalConfig()},methods:{editorInit:function(){e("2099"),e("be9d"),e("2968"),e("e0e5"),e("bb36"),e("0329"),e("95b8"),e("6a21")},loadCanalConfig:function(){var n=this;i().then(function(t){var e=t.data;n.form.id=e.id,n.form.name=e.name,n.form.content=e.content})},onSubmit:function(){var n=this;this.$confirm("修改Server主配置可能会导致Server重启,是否继续?","确定修改",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then(function(){r(n.form).then(function(t){"success"===t.data?(n.$message({message:"修改成功",type:"success"}),n.loadCanalConfig()):n.$message({message:"修改失败",type:"error"})})})},onCancel:function(){this.loadCanalConfig()}}},s=f,u=(e("fbdc"),e("2877")),l=Object(u["a"])(s,o,a,!1,null,"250c9dcc",null);t["default"]=l.exports},8351:function(n,t,e){},fbdc:function(n,t,e){"use strict";var o=e("8351"),a=e.n(o);a.a}}]);

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-7279d7fc.22670fea.js


+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-7ec889b7.6ba68ef0.js → canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-7ec889b7.192dc04c.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-e1a839e4.3175ead5.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
canal-admin/canal-admin-server/src/main/resources/public/static/js/chunk-e1a839e4.c870a02b.js


+ 20 - 0
canal-admin/canal-admin-server/src/test/java/com/alibaba/otter/canal/admin/jmx/JMXConnectionTest.java

@@ -0,0 +1,20 @@
+package com.alibaba.otter.canal.admin.jmx;
+
+import org.junit.Test;
+
+public class JMXConnectionTest {
+
+    @Test
+    public void testSimple() {
+
+        JMXConnection jmxConnection = new JMXConnection("127.0.0.1", 11113);
+        try {
+            CanalServerMXBean canalServerMXBean = jmxConnection.getCanalServerMXBean();
+            System.out.println(canalServerMXBean.getStatus());
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            jmxConnection.close();
+        }
+    }
+}

+ 14 - 14
canal-admin/canal-admin-ui/src/router/index.js

@@ -78,48 +78,48 @@ export const constantRoutes = [
     children: [
       {
         path: 'nodeServers',
-        name: '节点状态',
+        name: 'Server 状态',
         component: () => import('@/views/canalServer/NodeServer'),
-        meta: { title: '节点管理', icon: 'tree' }
+        meta: { title: 'Server 管理', icon: 'tree' }
       },
       {
         path: 'config',
-        name: 'Canal主配置',
+        name: 'Server 全局配置',
         component: () => import('@/views/canalServer/Config'),
-        meta: { title: 'Canal主配置', icon: 'form' }
+        meta: { title: 'Server 全局配置', icon: 'form' }
       },
       {
         path: 'canalInstances',
-        name: '实例管理',
+        name: 'Instance 管理',
         component: () => import('@/views/canalServer/CanalInstance'),
-        meta: { title: '实例管理', icon: 'nested' }
+        meta: { title: 'Instance 管理', icon: 'nested' }
       },
       {
         path: 'canalInstance/add',
-        name: '新建实例配置',
+        name: '新建Instance配置',
         component: () => import('@/views/canalServer/CanalInstanceAdd'),
-        meta: { title: '新建实例配置' },
+        meta: { title: '新建Instance配置' },
         hidden: true
       },
       {
         path: 'canalInstance/modify',
-        name: '修改实例配置',
+        name: '修改Instance配置',
         component: () => import('@/views/canalServer/CanalInstanceUpdate'),
-        meta: { title: '修改实例配置' },
+        meta: { title: '修改Instance配置' },
         hidden: true
       },
       {
         path: 'nodeServer/log',
-        name: 'Canal日志',
+        name: 'Server 日志',
         component: () => import('@/views/canalServer/CanalLogDetail'),
-        meta: { title: 'Canal日志' },
+        meta: { title: 'Server 日志' },
         hidden: true
       },
       {
         path: 'canalInstance/log',
-        name: 'Canal Instance日志',
+        name: 'Instance 日志',
         component: () => import('@/views/canalServer/CanalInstanceLogDetail'),
-        meta: { title: 'Canal Instance日志' },
+        meta: { title: 'Instance 日志' },
         hidden: true
       }
     ]

+ 23 - 23
canal-admin/canal-admin-ui/src/views/canalServer/CanalInstance.vue

@@ -1,10 +1,10 @@
 <template>
   <div class="app-container">
     <div class="filter-container">
-      <el-input v-model="listQuery.name" placeholder="实例名称" style="width: 200px;" class="filter-item" />
+      <el-input v-model="listQuery.name" placeholder="Instance 名称" style="width: 200px;" class="filter-item" />
       <el-button class="filter-item" type="primary" icon="el-icon-search" plain @click="fetchData()">查询</el-button>
       &nbsp;&nbsp;
-      <el-button class="filter-item" type="primary" @click="handleCreate()">新建实例</el-button>
+      <el-button class="filter-item" type="primary" @click="handleCreate()">新建 Instance</el-button>
       <el-button class="filter-item" type="info" @click="fetchData()">刷新列表</el-button>
     </div>
     <el-table
@@ -15,12 +15,12 @@
       fit
       highlight-current-row
     >
-      <el-table-column label="实例名称" min-width="200" align="center">
+      <el-table-column label="Instance 名称" min-width="200" align="center">
         <template slot-scope="scope">
           {{ scope.row.name }}
         </template>
       </el-table-column>
-      <el-table-column label="运行节点" min-width="200" align="center">
+      <el-table-column label="运行Server" min-width="200" align="center">
         <template slot-scope="scope">
           <span>{{ scope.row.nodeIp }}</span>
         </template>
@@ -37,20 +37,20 @@
               操作<i class="el-icon-arrow-down el-icon--right" />
             </el-button>
             <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item @click.native="handleUpdate(scope.row)">修改实例</el-dropdown-item>
-              <el-dropdown-item @click.native="handleDelete(scope.row)">删除实例</el-dropdown-item>
-              <el-dropdown-item @click.native="handleStart(scope.row)">启动服务</el-dropdown-item>
-              <el-dropdown-item @click.native="handleStop(scope.row)">停止服务</el-dropdown-item>
-              <el-dropdown-item @click.native="handleLog(scope.row)">日志详情</el-dropdown-item>
+              <el-dropdown-item @click.native="handleUpdate(scope.row)">修改</el-dropdown-item>
+              <el-dropdown-item @click.native="handleDelete(scope.row)">删除</el-dropdown-item>
+              <el-dropdown-item @click.native="handleStart(scope.row)">启动</el-dropdown-item>
+              <el-dropdown-item @click.native="handleStop(scope.row)">停止</el-dropdown-item>
+              <el-dropdown-item @click.native="handleLog(scope.row)">日志</el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
         </template>
       </el-table-column>
     </el-table>
-    <el-dialog :visible.sync="dialogFormVisible" title="确定启动服务" width="400px">
-      <el-form ref="dataForm" :rules="rules" :model="nodeModel" label-position="left" label-width="80px" style="width: 350px; margin-left:30px;">
-        <el-form-item label="选择节点" prop="nodeId">
-          <el-select v-model="nodeModel.id" placeholder="选择节点">
+    <el-dialog :visible.sync="dialogFormVisible" title="确定启动Instance" width="500px">
+      <el-form ref="dataForm" :rules="rules" :model="nodeModel" label-position="left" label-width="120px" style="width: 350px; margin-left:30px;">
+        <el-form-item label="选择运行Server" prop="nodeId">
+          <el-select v-model="nodeModel.id" placeholder="选择运行Server">
             <el-option v-for="item in nodeServices" :key="item.id" :label="item.name" :value="item.id" />
           </el-select>
         </el-form-item>
@@ -92,7 +92,7 @@ export default {
         id: null
       },
       rules: {
-        id: [{ required: true, message: '请选择节点', trigger: 'change' }]
+        id: [{ required: true, message: '请选择运行Server', trigger: 'change' }]
       }
     }
   },
@@ -114,7 +114,7 @@ export default {
       this.$router.push('/canalServer/canalInstance/modify?id=' + row.id)
     },
     handleDelete(row) {
-      this.$confirm('删除实例配置会导致Canal实例停止', '确定删除实例信息', {
+      this.$confirm('删除Instance配置会导致停止', '确定删除Instance信息', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
         type: 'warning'
@@ -123,12 +123,12 @@ export default {
           if (res.data === 'success') {
             this.fetchData()
             this.$message({
-              message: '删除实例信息成功',
+              message: '删除Instance信息成功',
               type: 'success'
             })
           } else {
             this.$message({
-              message: '删除实例点信息失败',
+              message: '删除Instance信息失败',
               type: 'error'
             })
           }
@@ -137,7 +137,7 @@ export default {
     },
     handleStart(row) {
       if (row.nodeId !== null) {
-        this.$message({ message: '当前实例不是停止状态,无法启动', type: 'error' })
+        this.$message({ message: '当前Instance已处于启动状态!', type: 'error' })
         return
       }
 
@@ -164,7 +164,7 @@ export default {
           this.dialogFormVisible = false
         } else {
           this.$message({
-            message: '启动实例服务出现异常',
+            message: '启动Instance出现异常',
             type: 'error'
           })
         }
@@ -172,10 +172,10 @@ export default {
     },
     handleStop(row) {
       if (row.nodeId === null) {
-        this.$message({ message: '当前实例不是启动状态,无法停止', type: 'error' })
+        this.$message({ message: '当前Instance已处于停止状态!', type: 'error' })
         return
       }
-      this.$confirm('停止Canal Instance: ' + row.name, '确定停止实例服务', {
+      this.$confirm('停止Instance: ' + row.name, '确定停止Instance服务', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
         type: 'warning'
@@ -189,7 +189,7 @@ export default {
             })
           } else {
             this.$message({
-              message: '停止实例服务出现异常',
+              message: '停止Instance出现异常',
               type: 'error'
             })
           }
@@ -198,7 +198,7 @@ export default {
     },
     handleLog(row) {
       if (row.nodeId === null) {
-        this.$message({ message: '当前实例不是启动状态,无法查看日志', type: 'warning' })
+        this.$message({ message: '当前Instance不是启动状态,无法查看日志', type: 'warning' })
         return
       }
       this.$router.push('canalInstance/log?id=' + row.id + '&nodeId=' + row.nodeId)

+ 3 - 3
canal-admin/canal-admin-ui/src/views/canalServer/CanalInstanceAdd.vue

@@ -2,9 +2,9 @@
   <div>
     <el-form ref="form" :model="form">
       <div class="filter-container" style="padding-left: 10px;padding-top: 20px;">
-        <el-input v-model="form.name" placeholder="实例名称" style="width: 200px;" class="filter-item" />
+        <el-input v-model="form.name" placeholder="Instance名称" style="width: 200px;" class="filter-item" />
         &nbsp;
-        <el-button class="filter-item" type="primary" @click="onSubmit">新建</el-button>
+        <el-button class="filter-item" type="primary" @click="onSubmit">保存</el-button>
         <el-button class="filter-item" type="info" @click="onBack">返回</el-button>
       </div>
       <editor v-model="form.content" lang="properties" theme="chrome" width="100%" :height="800" @init="editorInit" />
@@ -43,7 +43,7 @@ export default {
     onSubmit() {
       if (this.form.name === '') {
         this.$message({
-          message: '请输入实例名称',
+          message: '请输入Instance名称',
           type: 'error'
         })
         return

+ 1 - 1
canal-admin/canal-admin-ui/src/views/canalServer/CanalInstanceUpdate.vue

@@ -54,7 +54,7 @@ export default {
     },
     onSubmit() {
       this.$confirm(
-        '修改Canal实例配置可能会导致实例重启,是否继续?',
+        '修改Instance配置可能会导致重启,是否继续?',
         '确定修改',
         {
           confirmButtonText: '确定',

+ 1 - 1
canal-admin/canal-admin-ui/src/views/canalServer/Config.vue

@@ -53,7 +53,7 @@ export default {
     },
     onSubmit() {
       this.$confirm(
-        '修改Canal主配置可能会导致Server重启,是否继续?',
+        '修改Server主配置可能会导致Server重启,是否继续?',
         '确定修改',
         {
           confirmButtonText: '确定',

+ 32 - 32
canal-admin/canal-admin-ui/src/views/canalServer/NodeServer.vue

@@ -1,11 +1,11 @@
 <template>
   <div class="app-container">
     <div class="filter-container">
-      <!-- <el-input v-model="listQuery.name" placeholder="节点名称" style="width: 200px;" class="filter-item" />
-      <el-input v-model="listQuery.ip" placeholder="节点IP" style="width: 200px;" class="filter-item" />
+      <!-- <el-input v-model="listQuery.name" placeholder="Server 名称" style="width: 200px;" class="filter-item" />
+      <el-input v-model="listQuery.ip" placeholder="Server IP" style="width: 200px;" class="filter-item" />
       <el-button class="filter-item" type="primary" icon="el-icon-search" plain @click="fetchData()">查询</el-button> -->
-      <el-button class="filter-item" type="primary" @click="handleCreate()">新建节点</el-button>
-      <el-button class="filter-item" type="info" @click="fetchData()">刷新节点</el-button>
+      <el-button class="filter-item" type="primary" @click="handleCreate()">新建Server</el-button>
+      <el-button class="filter-item" type="info" @click="fetchData()">刷新列表</el-button>
     </div>
     <el-table
       v-loading="listLoading"
@@ -15,17 +15,17 @@
       fit
       highlight-current-row
     >
-      <el-table-column label="节点名称" min-width="200" align="center">
+      <el-table-column label="Server 名称" min-width="200" align="center">
         <template slot-scope="scope">
           {{ scope.row.name }}
         </template>
       </el-table-column>
-      <el-table-column label="IP" min-width="200" align="center">
+      <el-table-column label="Server IP" min-width="200" align="center">
         <template slot-scope="scope">
           <span>{{ scope.row.ip }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="端口" min-width="100" align="center">
+      <el-table-column label="JMX端口" min-width="100" align="center">
         <template slot-scope="scope">
           {{ scope.row.port }}
         </template>
@@ -47,29 +47,29 @@
               操作<i class="el-icon-arrow-down el-icon--right" />
             </el-button>
             <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item @click.native="handleUpdate(scope.row)">修改节点</el-dropdown-item>
-              <el-dropdown-item @click.native="handleDelete(scope.row)">删除节点</el-dropdown-item>
-              <el-dropdown-item @click.native="handleStart(scope.row)">启动服务</el-dropdown-item>
-              <el-dropdown-item @click.native="handleStop(scope.row)">停止服务</el-dropdown-item>
-              <el-dropdown-item @click.native="handleLog(scope.row)">日志详情</el-dropdown-item>
+              <el-dropdown-item @click.native="handleUpdate(scope.row)">修改</el-dropdown-item>
+              <el-dropdown-item @click.native="handleDelete(scope.row)">删除</el-dropdown-item>
+              <el-dropdown-item @click.native="handleStart(scope.row)">启动</el-dropdown-item>
+              <el-dropdown-item @click.native="handleStop(scope.row)">停止</el-dropdown-item>
+              <el-dropdown-item @click.native="handleLog(scope.row)">日志</el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
         </template>
       </el-table-column>
     </el-table>
     <el-dialog :visible.sync="dialogFormVisible" :title="textMap[dialogStatus]" width="600px">
-      <el-form ref="dataForm" :rules="rules" :model="nodeModel" label-position="left" label-width="80px" style="width: 350px; margin-left:80px;">
-        <el-form-item label="节点名称" prop="name">
+      <el-form ref="dataForm" :rules="rules" :model="nodeModel" label-position="left" label-width="120px" style="width: 400px; margin-left:30px;">
+        <el-form-item label="Server 名称" prop="name">
           <el-input v-model="nodeModel.name" />
         </el-form-item>
-        <el-form-item label="节点IP" prop="ip">
+        <el-form-item label="Server IP" prop="ip">
           <el-input v-model="nodeModel.ip" />
         </el-form-item>
-        <el-form-item label="节点端口" prop="port">
+        <el-form-item label="JMX端口" prop="port">
           <el-input v-model="nodeModel.port" placeholder="11113" type="number" />
         </el-form-item>
         <el-form-item label="监控端口" prop="port2">
-          <el-input v-model="nodeModel.port2" type="number" />
+          <el-input v-model="nodeModel.port2" placeholder="11112" type="number" />
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -112,20 +112,20 @@ export default {
       },
       dialogFormVisible: false,
       textMap: {
-        create: '新建节点信息',
-        update: '修改节点信息'
+        create: '新建Server信息',
+        update: '修改Server信息'
       },
       nodeModel: {
         id: undefined,
         name: null,
         ip: null,
         port: 11113,
-        port2: null
+        port2: 11112
       },
       rules: {
-        name: [{ required: true, message: '节点名称不能为空', trigger: 'change' }],
-        ip: [{ required: true, message: '节点IP不能为空', trigger: 'change' }],
-        port: [{ required: true, message: '节点端口不能为空', trigger: 'change' }]
+        name: [{ required: true, message: 'Server 名称不能为空', trigger: 'change' }],
+        ip: [{ required: true, message: 'Server IP不能为空', trigger: 'change' }],
+        port: [{ required: true, message: 'Server JMX端口不能为空', trigger: 'change' }]
       },
       dialogStatus: 'create'
     }
@@ -200,7 +200,7 @@ export default {
       })
     },
     handleDelete(row) {
-      this.$confirm('删除节点信息并不会导致节点服务停止', '确定删除节点信息', {
+      this.$confirm('删除Server信息并不会导致节点服务停止', '确定删除Server信息', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
         type: 'warning'
@@ -209,12 +209,12 @@ export default {
           if (res.data === 'success') {
             this.fetchData()
             this.$message({
-              message: '删除节点信息成功',
+              message: '删除Server信息成功',
               type: 'success'
             })
           } else {
             this.$message({
-              message: '删除节点信息失败',
+              message: '删除Server信息失败',
               type: 'error'
             })
           }
@@ -223,10 +223,10 @@ export default {
     },
     handleStart(row) {
       if (row.status !== 0) {
-        this.$message({ message: '当前节点不是停止状态,无法启动', type: 'error' })
+        this.$message({ message: '当前Server不是停止状态,无法启动', type: 'error' })
         return
       }
-      this.$confirm('启动节点 Canal Server 服务', '确定启动节点服务', {
+      this.$confirm('启动Server服务', '确定启动Server服务', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
         type: 'warning'
@@ -240,7 +240,7 @@ export default {
             })
           } else {
             this.$message({
-              message: '启动节点服务出现异常',
+              message: '启动Server服务出现异常',
               type: 'error'
             })
           }
@@ -249,10 +249,10 @@ export default {
     },
     handleStop(row) {
       if (row.status !== 1) {
-        this.$message({ message: '当前节点不是启动状态,无法停止', type: 'error' })
+        this.$message({ message: '当前Server不是启动状态,无法停止', type: 'error' })
         return
       }
-      this.$confirm('停止节点 Canal Server 服务', '确定停止节点服务', {
+      this.$confirm('停止 Server 服务', '确定停止Server服务', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
         type: 'warning'
@@ -266,7 +266,7 @@ export default {
             })
           } else {
             this.$message({
-              message: '停止节点服务出现异常',
+              message: '停止Server服务出现异常',
               type: 'error'
             })
           }

+ 16 - 11
client-adapter/common/src/main/java/com/alibaba/otter/canal/client/adapter/support/AbstractEtlService.java

@@ -1,24 +1,26 @@
 package com.alibaba.otter.canal.client.adapter.support;
 
-import com.alibaba.druid.pool.DruidDataSource;
-import com.google.common.base.Joiner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.sql.DataSource;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicLong;
 
+import javax.sql.DataSource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.google.common.base.Joiner;
+
 public abstract class AbstractEtlService {
 
-    protected Logger      logger = LoggerFactory.getLogger(this.getClass());
+    protected Logger      logger       = LoggerFactory.getLogger(this.getClass());
 
     private String        type;
     private AdapterConfig config;
-    private final long CNT_PER_TASK = 10000L;
+    private final long    CNT_PER_TASK = 10000L;
 
     public AbstractEtlService(String type, AdapterConfig config){
         this.type = type;
@@ -43,7 +45,6 @@ public abstract class AbstractEtlService {
             // 拼接条件
             if (config.getMapping().getEtlCondition() != null && params != null) {
                 String etlCondition = config.getMapping().getEtlCondition();
-                int size = params.size();
                 for (String param : params) {
                     etlCondition = etlCondition.replace("{}", "?");
                     values.add(param);
@@ -87,8 +88,12 @@ public abstract class AbstractEtlService {
                 for (long i = 0; i < workerCnt; i++) {
                     offset = size * i;
                     String sqlFinal = sql + " LIMIT " + offset + "," + size;
-                    Future<Boolean> future = executor.submit(
-                        () -> executeSqlImport(dataSource, sqlFinal, values, config.getMapping(), impCount, errMsg));
+                    Future<Boolean> future = executor.submit(() -> executeSqlImport(dataSource,
+                        sqlFinal,
+                        values,
+                        config.getMapping(),
+                        impCount,
+                        errMsg));
                     futures.add(future);
                 }
 

+ 3 - 3
client-adapter/launcher/src/main/java/com/alibaba/otter/canal/adapter/launcher/loader/AbstractCanalAdapterWorker.java

@@ -6,7 +6,6 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
-import com.alibaba.fastjson.JSON;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -152,8 +151,9 @@ public abstract class AbstractCanalAdapterWorker {
                     if (flatMessage) {
                         // batch write
                         writeOut((List<FlatMessage>) messages);
-                        //FIXME xxx
-                        messages.forEach((message -> System.out.println(JSON.toJSONString(message))));
+                        // FIXME xxx
+                        // messages.forEach((message ->
+                        // System.out.println(JSON.toJSONString(message))));
                     } else {
                         for (final Object message : messages) {
                             writeOut((Message) message);

+ 10 - 6
client-adapter/rdb/src/main/java/com/alibaba/otter/canal/client/adapter/rdb/RdbAdapter.java

@@ -23,7 +23,11 @@ import com.alibaba.otter.canal.client.adapter.rdb.service.RdbEtlService;
 import com.alibaba.otter.canal.client.adapter.rdb.service.RdbMirrorDbSyncService;
 import com.alibaba.otter.canal.client.adapter.rdb.service.RdbSyncService;
 import com.alibaba.otter.canal.client.adapter.rdb.support.SyncUtil;
-import com.alibaba.otter.canal.client.adapter.support.*;
+import com.alibaba.otter.canal.client.adapter.support.Dml;
+import com.alibaba.otter.canal.client.adapter.support.EtlResult;
+import com.alibaba.otter.canal.client.adapter.support.OuterAdapterConfig;
+import com.alibaba.otter.canal.client.adapter.support.SPI;
+import com.alibaba.otter.canal.client.adapter.support.Util;
 
 /**
  * RDB适配器实现类
@@ -73,8 +77,8 @@ public class RdbAdapter implements OuterAdapter {
         // 过滤不匹配的key的配置
         rdbMappingTmp.forEach((key, mappingConfig) -> {
             if ((mappingConfig.getOuterAdapterKey() == null && configuration.getKey() == null)
-                || (mappingConfig.getOuterAdapterKey() != null
-                    && mappingConfig.getOuterAdapterKey().equalsIgnoreCase(configuration.getKey()))) {
+                || (mappingConfig.getOuterAdapterKey() != null && mappingConfig.getOuterAdapterKey()
+                    .equalsIgnoreCase(configuration.getKey()))) {
                 rdbMapping.put(key, mappingConfig);
             }
         });
@@ -134,8 +138,8 @@ public class RdbAdapter implements OuterAdapter {
         String threads = properties.get("threads");
         // String commitSize = properties.get("commitSize");
 
-        boolean skipDupException = BooleanUtils
-            .toBoolean(configuration.getProperties().getOrDefault("skipDupException", "true"));
+        boolean skipDupException = BooleanUtils.toBoolean(configuration.getProperties()
+            .getOrDefault("skipDupException", "true"));
         rdbSyncService = new RdbSyncService(dataSource,
             threads != null ? Integer.valueOf(threads) : null,
             skipDupException);
@@ -181,7 +185,7 @@ public class RdbAdapter implements OuterAdapter {
         MappingConfig config = rdbMapping.get(task);
         RdbEtlService rdbEtlService = new RdbEtlService(dataSource, config);
         if (config != null) {
-                return rdbEtlService.importData(params);
+            return rdbEtlService.importData(params);
         } else {
             StringBuilder resultMsg = new StringBuilder();
             boolean resSucc = true;

+ 5 - 0
client-adapter/rdb/src/main/java/com/alibaba/otter/canal/client/adapter/rdb/service/RdbSyncService.java

@@ -105,6 +105,11 @@ public class RdbSyncService {
                 List<Future<Boolean>> futures = new ArrayList<>();
                 for (int i = 0; i < threads; i++) {
                     int j = i;
+                    if (dmlsPartition[j].isEmpty()) {
+                        // bypass
+                        continue;
+                    }
+
                     futures.add(executorThreads[i].submit(() -> {
                         try {
                             dmlsPartition[j].forEach(syncItem -> sync(batchExecutors[j],

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott