星期二, 10月 15, 2019

KafKa connect

 當你需要ETL 時  你會用啥工具
 其實找了很多東西  有些蠻好的 有 fluentd , oracle OGG ,  canal 都不錯的 但有一種算簡單 也方便的方式  目前還在測試中  就是 KafKa connect

不過基本的串接已經可以達成 主要用 new PK + timestamp 的方式 做 資料抽取

當Table有新資料時,最簡單的方式,就是 select PKey last 大於的方試,可以找出來.那如果有異動的 update 其實就可以用 timestamp last 大於的方式,也可以找出來.差別就是 你同步的最後一筆的資訊能作為撈取的區間為何.基本上也是要排序!!
  SELECT * FROM "TEST_USER" WHERE
  "TEST_USER"."MODIFIED" < ?  AND (("TEST_USER"."MODIFIED" = ?  AND "TEST_USER"."ID" > ?)
  OR "TEST_USER"."MODIFIED" > ?)  ORDER BY "TEST_USER"."MODIFIED","TEST_USER"."ID" ASC.


這是 KafKa connect 下的條件 其實就是不停的  Query然後抓到的 Data 放進 Kafa Queue 裡但這也只是一半 還要處理 寫入 必須去重   說方便 但也不是非常聰明 ,至少能做到 insert update 的同步



建立 Kafka Connect sink 寫入  請使用5.3版 db.timezone 很重要的

curl -X POST http://192.168.250.35:8083/connectors -H "Content-Type: application/json" -d '{
    "name": "jdbc-sink",
    "config": {
            "connector.class": "io.confluent.connect.jdbc.JdbcSinkConnector",
            "connection.url": "jdbc:oracle:thin:@192.168.250.233:1521/dbcenter",
            "connection.user": "xxx",
            "connection.password": "xxx",
            "topics": "TEST_USER",
            "name": "jdbc-sink",
            "insert.mode":"upsert",
            "db.timezone":"Asia/Shanghai",
            "auto.create": "true",
            "auto.evolve":"true",
            "pk.fields":"ID",
            "pk.mode":"record_value"
            }
    }'

從 topics
往目標DB 丟資訊 使用 upsert
對Oracle 剛好是merge 的方式


建立 Kafka Connect Source 讀取

curl -X POST http://192.168.250.35:8083/connectors -H "Content-Type: application/json" -d '{
            "name": "jdbc_source_oracle_01",
            "config": {
                    "connector.class": "io.confluent.connect.jdbc.JdbcSourceConnector",
                    "connection.url": "jdbc:oracle:thin:@192.168.0.230:1521/dbcenter",
                    "connection.user": "xxx",
                    "connection.password": "xxx",
                    "table.types":"TABLE",
                    "topic.prefix": "",
                    "table.whitelist" : "TEST_USER",
                    "mode":"timestamp",
                    "timestamp.column.name":"MODIFIED",
                    "poll.interval.ms" : 5000,
                    "db.timezone":"Asia/Shanghai",
                    "validate.non.null": false
                    }
            }'

以上配置就能 用  ID and timestamp 做基本的 抽取備份 這範例是 Oracle to Oracle使用 JdbcSourceConnector
記得要裝 ojdbc.jar 放在share 的資料夾就可以了

https://docs.confluent.io/current/connect/references/allconfigs.html 配置細節

更多 connector 配置細節
https://docs.confluent.io/current/connect/kafka-connect-jdbc/source-connector/index.html

https://docs.confluent.io/current/connect/index.html

https://docs.confluent.io/current/connect/managing/monitoring.html





玩弄Kafka

如果你只是想拿來當 Queue   這個功能就過之了

也可能沒這樣好用 裝個rabbitmq 可能會很好 還有比較好的介面使用


用conflunt 裝好 也啟動之後 就來 弄個 consumer吧

/bin 底下 有很多 執行 shell 可以使用


 ./kafka-console-consumer --bootstrap-server 127.0.0.1:9092 --from-beginning --topic TEST

--from-beginning  會從 0 開始 沒有offset

但是這樣會從 Topic Test裡面 拿出從古至今所有的 Data
如果不需要 就拿掉這段 就是一般的 先進先出 Queue


弄個 Producer吧

./kafka-console-producer --broker-list localhost:9092 --topic test

Standard Input 輸入幾個 Msg
另一編的 consumer 就收到訊息了
簡易的  KafKa 就 完成了

confluent kafka 速記

最近在玩Kafka

confluent 整合kafka 的生態系 包含zookeeper ksql connect 


使用套件  confluent  安裝 版本  5.3.1  從 https://www.confluent.io 下載之後 zip 檔案之後 解開

第一次使用時 用的是 5.1 有幾個 connector 的 bug 5.3 就修正了 這邊直接用 5.3.1 的方式 紀錄一下

先幫 confluent/bin 加入   環境變數



vi /etc/profile
export PATH=/root/confluent-5.3.1/bin:$PATH
source /etc/profile



然後 5.3 之後需要 下載 cli 使用

curl -L https://cnfl.io/cli | sh -s -- -b /<path-to-directory>/bin

https://docs.confluent.io/current/cli/installing.html

放到  /bin 後  就可以用了


confluent local start  就可以啟動  kafka  然後進行測試
如果需要 connect 

control-center.properties   


confluent.controlcenter.connect.cluster=http://localhost:8083

confluent.controlcenter.connect.connect-default.cluster=http://localhost:8083


這需要打開  

connect-default 是local 預設的  配置項


基本上就 搞定了  再來就可以去玩 kafka 




下篇會 寫點 connect 小小的紀錄



星期日, 1月 06, 2019

webpack memo

npm cache clean --force

npm install
npm run prod:d
npm run prod:m



editbin.exe /NXCOMPAT:NO c:\project\bin\Release\WindowsFormsApplication.exe

星期二, 4月 04, 2017

星期一, 3月 13, 2017

docker docekr

  1. docker-machine start default or create new one
  2. docker-machine lswill show you your machine running
  3. docker-machine env --shell cmd default and you'll see something like
    SET DOCKER_TLS_VERIFY=1
    SET DOCKER_HOST=tcp://192.168.99.100:2376
    SET DOCKER_CERT_PATH=C:\Users\Arseny\.docker\machine\machines\default
    SET DOCKER_MACHINE_NAME=default
    REM Run this command to configure your shell:
    REM     FOR /f "tokens=*" %i IN ('docker-machine env --shell cmd default') DO %i



docker build -f Dockerfile -t mnlmajhon:latest .

docker run —name majhon —restart always -p 5000:5000 mnlmajhon:latest

星期四, 5月 05, 2016

自動發布 IOS Android


先clean
xcodebuild clean -configuration Distribution

後 Buildxcodebuild -scheme Caipiao archive -archivePath /Users/mdd/Desktop/Caipiao


再打包
exportProvisioningProfile  是憑證名稱

xcodebuild -exportArchive -exportFormat ipa -archivePath "/Users/mdd/Desktop/Caipiao.xcarchive" -exportPath "/Users/mdd/Desktop/Caipiao.ipa" -exportProvisioningProfile "Caipiao Distribution Push with 2016sign @April 3"



Andoird 使用  Debug Keystore 


android update project --name Lottery -p D:\project\mobile\trunk\Android\Lottery 

星期二, 12月 02, 2014

手把手 Ror

sudo apt-get install ImageMagick

 rake generate_secret_token
   rake db:migrate RAILS_ENV="production"

星期二, 11月 25, 2014

Jmeter 使用實況

壓測工具 算蠻有意思的   最近完了兩套 loadrunner && Jmeter 一個要錢,一個不用錢,loadrunner 12之後 授權方式改了 50個vuser  不用錢 ,所以 等於試玩不用錢。


選proxy 後 再到瀏覽器裡去設定 proxy localhost 8080 當你的瀏覽器 就會經過這個 Jmeter 的proxy ,這邊我是用firefox 去配合。
之後 就可以開始錄製,如果有需要使用cookies 就要加入cookies manager,這次測試的網站的cookie使用上 會有錯就必須自己去抓 cookies。

使用後置處理器裡的正規式轉換可以把需要的內容 拿出來再使用成變數${ XXX } 到之後需要的地方。

這次的cookies 有一些奇怪的東西會造成初始化的內容不正確,引響到其他部分的操作,這些測試程式能做的事還很多,當然也要好好的去try 你的網站,如果 加上能破解captcha的功能,那就更好了。







星期四, 10月 02, 2014

Eclipse JDK 改路徑

 Eclipse 時會去抓JRE的目錄 ,而不是JDK。



compiler 時會出現問題,記得把它改掉。

星期四, 9月 11, 2014

CentOS 工作備份

CentOS 7.0 安裝片

安裝 Nginx 
         mangodb
         php 5.4 up
         mysql 5.5


yum 已經可以裝到 php5.4 up 和 mysql 5.6 


來裝 NGinx 吧
https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-centos-7
這邊有說明 


sudo rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

sudo yum install nginx

Step Three—Start Nginx

sudo systemctl start nginx.service

星期二, 4月 01, 2014

HG svn Covert 中文

 def putcommit(self, files, copies, parents, commit, source, revmap):

        ### gegogi mod ###
        def _cp949(s):
            return s.decode('utf-8').encode('cp950')
        def _utf8(s):
            return s.decode('cp950').encode('utf-8')
        ##################

        files = dict(files)

        ### gegogi mod ###
        for k, v in files.items():
            del files[k]
            files[_cp949(k)] = v
        for k, v in copies.items():
            del copies[k]
            copies[_cp949(k)] = _cp949(v)
        ##################

        def getfilectx(repo, memctx, f):
            ### gegogi mod ###
            v = files[f]
            data , e= source.getfile(_utf8(f), v)
            if f == '.hgtags':
                data = self._rewritetags(source, revmap, data)
            return context.memfilectx(f, data, 'l' in e, 'x' in e, copies.get(f))
            ##################

        pl = []
        for p in parents:
            if p not in pl:
                pl.append(p)
        parents = pl
        nparents = len(parents)
        if self.filemapmode and nparents == 1:
            m1node = self.repo.changelog.read(bin(parents[0]))[0]
            parent = parents[0]

        if len(parents) < 2:
            parents.append(nullid)
        if len(parents) < 2:
            parents.append(nullid)
        p2 = parents.pop(0)

        text = commit.desc
        extra = commit.extra.copy()
        if self.branchnames and commit.branch:
            extra['branch'] = commit.branch
        if commit.rev:
            extra['convert_revision'] = commit.rev

        while parents:
            p1 = p2
            p2 = parents.pop(0)
            ctx = context.memctx(self.repo, (p1, p2), text, files.keys(),
                                 getfilectx, commit.author, commit.date, extra)
            self.repo.commitctx(ctx)
            text = "(octopus merge fixup)\n"
            p2 = hex(self.repo.changelog.tip())

        if self.filemapmode and nparents == 1:
            man = self.repo.manifest
            mnode = self.repo.changelog.read(bin(p2))[0]
            closed = 'close' in commit.extra
            if not closed and not man.cmp(m1node, man.revision(mnode)):
                self.ui.status(_("filtering out empty revision\n"))
                self.repo.rollback(force=True)
                return parent
        return p2

星期三, 9月 04, 2013

Upper_bound
Lower_bound

int myints[] = {10,20,30,30,20,10,10,20};
std::vector v(myints,myints+8);           // 10 20 30 30 20 10 10 20

std::sort (v.begin(), v.end());                // 10 10 10 20 20 20 30 30
std::cout << std::endl;
for (std::vector::iterator it = v.begin(); it != v.end(); it++)
{

std::cout << " " << *it << " ";

}
std::cout << std::endl;
std::vector::iterator low,up;
low=std::lower_bound (v.begin(), v.end(), 10); //          ^
up= std::upper_bound (v.begin(), v.end(), 10); //                   ^


找出 指定數值的位置   排序後
位置 0 -> 10 lower_bound  = 0
位置 3 -> 20 但是前一個是10  所以 upper_bound  = 3
 

星期二, 8月 27, 2013

星期四, 8月 08, 2013

從無到有 3D MMO 要做多少事

基本上會找一個現有 3D Engine 會比重新刻好,除非你是大師級的,因為要花的時間真的不少。

3D Game Engine要有些什麼 功能?

3d Max的plugin 轉換 Engine裡面所使用的 model檔
場景編輯器
遊戲事件編輯器
Cute scene 編輯器
UI 編輯器
動態編輯器
觀看物件的 Object View。
如果有網路就要 寫網路的部份
檔案Patch 機制 壓縮方法... 等 。
大概需要的框架就是這些,還不包括企劃需要的文件系統。

其實可以參考 OGRE http://www.ogre3d.org/


其實很多人不瞭解這東西到底做了什麼事,這邊來整理一下好了。
乾脆就把他分開變成 遊戲引擎 和 3D影擎。

3D的部份就管電腦圖學的部份 ,3D物件的演算使用、3D 物件Animation、Shader、地型、場景、燈光、影子、卡通效果...。
遊戲引擎就是 遊戲規則的編寫,遊戲內和3D物件互動的整合。
一款很完整的引擎,基本上會產出不少工具,使用不少技術,加上AI,這大概就是3D遊戲引擎。

比如說我要開始製做一款3D遊戲,一開始從建立3D model開始,從3D Max匯出物件檔就是工了。好的引擎會把建立物件的 Input output 最佳化,加上一些資訊,所以一開始會有3D Max的export。

把Model Load進Game後 你會需要 控制Model的資訊,所以要先製作些資料,比如說物件的大小、物件特效大小、物件特效顯示位置、物件可變換Avatar功能,走路的動作,受傷的動作,這時候第二個工具就會出現了,可能會叫做生物編輯器之類的。讓你可以編輯各種屬性和外觀。

有了生物但沒有場景,所以要有個場景編輯器,雖然可以用Max直接做整個場景出來,但如果要做出更多細部物件的控制,就要有個可以像拼拼圖一樣的編輯器,讓你能做出場景,加入場景的Model。

接下來你要能在地圖上編輯相關遊戲規則,所以又出現了一個新的工具。

然後有個正流行的cut scene 功能,可以製作遊戲內額外的表演。

以上為基本款。

接下來就要看需求方向加上更多東西。


3d 選取物件

通常都會是長這樣
Point3        Origin;  點選投射點
Point3        Dir;  點選向量
MousePos                                 滑鼠座標
GetCamera()->WindowPointToRay( MousePos.x, MousePos.y, Origin, Dir );

去換到 投攝的點 和向量之後在拿去和物件 算碰撞,有碰到的物件就可以選取


在利用  BoundObject去check

當然還可以拿到目前的距離

攝影機範圍
class Frustum
 {
   float m_fLeft;
    float m_fRight;
    float m_fTop;
    float m_fBottom;
    float m_fNear;
    float m_fFar;
    bool  m_bOrtho;
};

記憶一下

除了本來工作上的東西 ,還有些啥技術有瞭解到?

先是  Data-Driven 還有 Event-Driven  ,我書讀的少,真的看完了有這些Model的東西後,才瞭解啥是啥?

拿走路來講講,Event-Driven 的方事是當你有走動時的操作時才將Event 丟到你控制移動的功能,比如說你在畫面上 有一個點在(0,0),你點下座標(100,100)時,他接收到Event之後開始走過去;Data-Driven則是,你去控制你的點的座標,讓他到達(100,100),所以走路應該是兩個系統整合起來,而達到自動行走。

有些FPS的Game ,在移動時就是用Data-Driven,client端會一直向Server去詢求更改位置的固定 protocol之後,Server確認ok後回傳給Client新座標,Clien收到procotol 改變移動需要的動作,並設定新座標。所以如果client送protocol的速度很快Server又沒去擋掉不合理的部份,別人看起來就會像飛一樣。

我知道的MMO RPG,這邊就是Event-Driven,當你在畫面上點選了座標給Server,client自動的移動過去,這時候client固定會和server在ckeck position,確定可行走後繼續移動,到達目的地之後就不會再送資料給server。並不完全精準,有可能發生client 先到Server還沒通知別的client。

兩個系統有各自需求的部份,用太多Data-Driven對Server來說是負擔,用Event-Driven,誤差就必需去算回來。

認真來講 Timer也是一種Data-Drivern,而Mouse Click則是Event-Driven。

星期一, 12月 10, 2012

memo

#define _USE_ANSI_CPP #define _STATIC_CPPLIB #define _DISABLE_DEPRECATE_STATIC_CPPLIB

星期一, 11月 12, 2012

jar add 數位簽章

jarsigner -verify xxx .jar
可以知道有沒有簽過章
message :
 jar verified.

 or

 jar is unsigned.

 keytool -list -storetype pkcs12 -keystore xxx.pfx
輸入密碼
xxxxx-xxxx-xxxx-xx
之後出現評證指紋上的一堆字
jarsigner -storetype pkcs12 -keystore xxx.pfx xxx.jar xxxx-xxx-xxx-xxx
就簽上了

星期二, 4月 03, 2012

mac小記

macports
brew