Monorepos vs Multilrepos

Lang thang trên mạng tự nhiên gặp bài viết này [1] nên tò mò xem Momorepos là gì? Sau đó tìm hiểu thêm google thì có bài viết [2] [3] [4] giải thích và cho ví dụ khá rõ ràng.

Thì ra nó liên quan đến việc quản lý mã nguồn của dự án. Trước đây mình không để ý lắm nên không biết phân biệt giữa 2 khái niệm này. Khi dùng SVN thì công ty mình dùng theo kiểu Monorepos(mặc dù chưa biết đến thuật ngữ đó), nghĩa là có một Repository duy nhất được tạo ra, các dự án khác nhau đều tống chung vào đó, mỗi dự án là một thư mục được tạo ra. Tất nhiên vẫn phân quyền được bình thường theo từng thư mục.

Sau này khi chuyển sang Gitlab cùng với việc phát triển Microservice nên trên Gitlab mỗi một project thì đều tạo Repository riêng cho nó. Tương đương trên github mình làm các project nhỏ nhỏ khác cũng như vậy.

Sơ sơ thì mỗi cái lại có ưu và nhược điểm nhưng thấy nhiều ý kiến cho rằng đối với Startup và Công ty lớn ưa chuộng việc dùng Monorepos hơn như Google, Facebook…

[1]: https://medium.com/@hoangbkit/why-monorepo-in-2018-89221acd4bfb
[2]: https://www.reddit.com/r/devops/comments/8vgqhq/what_do_you_prefer_and_why_mono_repo_or_multiple/
[3]: https://www.atlassian.com/git/tutorials/monorepos
[4]: https://medium.com/@patrickleet/mono-repo-or-multi-repo-why-choose-one-when-you-can-have-both-e9c77bd0c668

Config send email from oracle database server

ORA-24247: network access denied by access control list (ACL)

Kiểm tra bằng cách chạy câu lệnh

select * from dba_network_acls;

Nếu có data dạng:

 HOST LOWER_PORT UPPER_PORT ACL  ACLID
 mail.vstv.vn    1   1024    /sys/acls/send_mail.xml D285E04B69B942688587AB8FE5B41C69 

Chạy câu lệnh này:

BEGIN
   DBMS_NETWORK_ACL_ADMIN.create_acl (
     acl          => 'send_mail.xml',
     description  => 'Purpose of the acl is to send mail',
     principal    => 'INTRANET',
     is_grant     => TRUE,
     privilege    => 'connect',
     start_date   => SYSTIMESTAMP,
     end_date     => NULL);
 DBMS_NETWORK_ACL_ADMIN.assign_acl (
     acl         => 'send_mail.xml',
     host        => 'mail.trituenhantao.info',
     lower_port  => 1,
     upper_port  => 1024);
 COMMIT;
 END;

Plugin Compare for Notepad++

Before, I usually using SVN to find the different points of version source code. But recently, I don’t use SVN or Source Code Management Tools other. Today, I can find the difference of a package Oracle with version before we upgrade.
I was recommended using plugin Compare for Notepad++ to work this it. It is perfect for me.

We has two ways to install Plugin Compare for Notepad++:
1: Install from Plugin Manager
Choice menu Plugins -> Plugins Admin…
Search: Compare and tick on Compare. Click Install.
After that, dialog display Notepad++ is about to exit ask confirm Notepad++ will restart to Apply plugin.
2: Install from package dowload
Dowload the last version Compare Plugin on link: https://sourceforge.net/projects/npp-compare/
Unzip file dowloaded, we have file ComparePlugin.dll
Choice Settings -> Import -> Import plugin(s)… Select the file ComparePlugin.dll

To compare, we open two file and select Plugins -> Compare -> Compare
Or press Alt + D

Unlock user Workspace Administrator on Apex

Bên mình làm hệ thống báo cáo bằng Apex. Khi muốn tạo hoặc sửa báo cáo phải vào trang quản trị ứng dụng với tài khoản:
DB: XXX
User: ADMIN1
Pass: Abcd1234
Hôm nay vào vì bị lock do nhiều lần nhập sai mật khẩu.

Địa chỉ để vào quản trị ứng dụng là http://111.111.111.111:7778/apex/
Địa chỉ để vào ứng dụng là: http://111.111.111.111:7778/apex/f?p=104:LOGIN:11636406781643:::::

Ứng dụng vẫn vào được bình thường nhưng phần quản trị ứng dụng bị báo lock user.

Các bước để unlock:
B1: Vào CMD gõ lần lượt các lệnh sau:

sqlplus /nolog
connect /as sysdba
alter session set current_schema = APEX_050100;
commit;
UPDATE Apex_050100.Wwv_Flow_Fnd_User

SET Web_Password = 'Abcd1234'

WHERE User_Name = 'ADMIN'

AND Security_Group_Id = 10;

COMMIT; 
begin
wwv_flow_security.g_security_group_id := 10;
wwv_flow_fnd_user_api.UNLOCK_ACCOUNT('ADMIN');
commit;
end;

Nếu cmd không tự ngắt để enter lệnh thì gõ / và nhấn Enter.

B2: Sửa trên ứng dụng

Địa chỉ quản trị Workspace: http://111.111.111.111:7778/apex/f?p=4550:10:13666886988498::NO:::
Đăng nhập với tài khoản: ADMIN / Abcd1234

Bấm vào Manage Workspaces.
Chọn Manage Developers and Users trong mục Workspace Actions
Chọn User cần Unlock, ở đây là ADMIN1
Tìm đến mục Account Availability. Chọn Unlocked.

Thế là xong, chỉ cần vào lại trang quản trị ứng dụng và nhập thông tin cũ là được.

Cài đặt Oracle 11g, 12c

Thử cài đặt Oracle trên Máy ảo linux hoặc window

https://o7planning.org/vi/10347/huong-dan-cai-dat-va-cau-hinh-database-oracle-12c

https://o7planning.org/vi/10211/huong-dan-cai-dat-va-cau-hinh-database-oracle-11g

Một chiến lược đảm bảo an toàn dữ liệu

Hiện mình đang làm cho một công ty X về việc cung cấp dịch vụ cho khách hàng. Hệ thống lưu trữ thông tin khách hàng bao gồm nhiều thứ như họ tên, số điện thoại email, thời hạn dịch vụ, lịch sử thanh toán…

Như các bạn đã biết, dữ liệu về khách hàng của công ty là cực kỳ quan trọng. Bài toán đảm bảo an toàn dữ liệu khách như vấn đề bảo mật, tránh mất mát dữ liệu, đảm bảo hệ thống luôn sẵn sàng… là những bài toán lớn cần được giải quyết. Qua tìm hiểu hệ thống và cóp nhặt trên mạng, mình nốt lại một số thông tin về lý do và cách thức việc đảm bảo an toàn dữ liệu.

Dữ liệu thì được nằm trên cơ sở dữ liệu, từ đó các ứng dụng truy cập vào hệ thống để thực hiện các thao tác xem, thêm, sửa xóa dữ liệu. Cơ sở dữ liệu luôn phải được đảm bảo sống, nghĩa là bất kỳ lúc nào cũng có thể truy vấn được. Tuy nhiên, không phải lúc nào hệ thống cũng ổn định, có thể lỗi ở phía server(phần cứng), lỗi ở phía hệ điều hành, lỗi ở phía hệ quản trị cơ sở dữ liệu…

Sau đây mình liệt kê các mức của hệ thống:

Tính sẵn sàng của hệ thống

Hiện tại hệ thống bên mình chỉ có duy nhất một DB đang Active. Hàng giờ hệ thống liên tục đồng bộ sang 2 DB ở chế độ Standby. Chỉ khi nào xảy ra sự cố đặc biệt nghiêm trọng, DB đang Active nguy cơ không thể hồi phục trong thời gian dài thì 1 trong 2 DB này mới được bật lên ở chế độ Active. Như vậy tính rủi ro khá cao.
Ở công ty Y cũ mình thì sử dụng cơ chế 3 Node DB để đảm bảo tính sẵn sàng của hệ thống. Nghĩa là hệ thống luôn luôn có 3 DB đều ở chế độ Active, sử dụng công nghệ RAC của Oracle. Khi 1 DB (1 Node) gặp trục trặc thì hệ thống vẫn hoạt động được bình thường. Tuy nhiên khả năng Failover của hệ thống thì mình không dám chắc (Failover là khái niệm về việc giao dịch đang xử lý ở Node lỗi có tiếp tục được xử lý ở Node khác không).

Đảm bảo an toàn dữ liệu

Mô hình hệ thống Active – Standby thì sau một khoảng thời gian cần phải cập nhật thông tin từ con Active sang con Standby sử dụng công nghệ Archive log của Oracle để copy các sự thay đổi sang con Standby. Hiện tại có 2 con Standby, một con nằm cùng Data Center với con Active, một con Standby nằm ở một Data Center khác.

  • Đối với việc lỗi phần cứng của con Active, trong thời gian ngắn không khắc phục được thì con Standby cùng Data Center sẽ được bật lên để tiếp tục đảm bảo dịch vụ.
  • Đối với việc lỗi cả Data Center về phần cứng, hạ tầng mạng… thì buộc phải bật con Standby ở Data Center khác.

Theo khuyến cáo thì các Data Center đặt dữ liệu của hệ thống nên đặt xa nhau hàng trăm KM. Việc này đề phòng các thiên tai có thể xảy đến trên một vùng lớn. Ví dụ bão đổ vào Miền Bắc, cụ thể là Hà Nội. Trường hợp các Data Center ở Hà Nội đều hỏng hết thì khi đó Data Center nằm ở Bình Dương hoặc TP Hồ Chí Minh phát huy tác dụng. Không những việc đảm bảo dịch vụ mà còn đảm bảo về tính toàn vẹn của dữ liệu.
Đối với công ty lớn, dịch vụ có thể là khu vực và toàn cầu thì việc đặt dữ liệu tại Data Center thứ cấp có thể phải đặt ở nước khác hoặc châu lục khác. Việc này đảm bảo khi có chiến tranh hoặc sự tấn công lên tầm quốc gia.

Đây là hiểu biết của mình ở thời điểm hiện tại. Sau mình cần tìm hiểu rõ hơn về các khái niệm: High Availability, Cluster, Network Load Balancer, Failover

Kết nối Python với MariaDB trên Anaconda

Trong nhiệm vụ crawl dữ liệu cho những dự án linh tinh của mình, việc cần thiết là phải lưu trữ lại các dữ liệu trong một hệ quản trị cơ sở dữ liệu nào đó, mình đã chọn MariaDB để làm điều này.
Vì việc lựa chọn Python trên Anaconda để thực hiện nên mình cần một hệ quản trị cơ sở dữ liệu nào đó vừa nhẹ, dễ sử dụng và quen thuộc. Đối với SQL Server và Oracle thì quá quen thuộc nhưng phải cài đặt nó mất rất nhiều thời gian mà không cần thiết vì nó hơi to so với dự án của mình. Với lại Oracle thì mình cũng đã kết nối được với Python rồi. Sử dụng No SQL thì mình đã từng sử dụng Nodejs kết nối với MongoDB thì thực sự mình không ưa cái anh MongoDB này lắm vì thấy cũng hơi phức tạp.
Cái tên quen thuộc nữa là MySQL, ban đầu định dùng nó nhưng đúng là lúc đó đang gặp vấn đề về việc cài đặt Xampp và Wampp lên máy tính ở nhà (do xung đột một số cổng của các phần mềm khác như Skype…). Với có thông tin rằng MySQL dần dần không còn là nguồn mở nữa, anh bạn Oracle đã mua lại và không còn được hào phóng như cộng đồng nguồn mở nữa. Cho nên cái nên MariaDB là lựa chọn cuối cùng của mình.

  • MariaDB là một phiên bản khác của MySQL và được cộng đồng nguồn mở dần chuyển qua để thay thế cho MySQL ngày càng đóng lại.
    Để cài đặt MariaDB thì khá đơn giản, hoàn toàn có thể cài đặt được ở máy tính cá nhân và trên server. Các bạn có thể vào địa chỉ: https://mariadb.com/downloads/#mariadb_platform-mariadb_server để tải về và cào đặt dễ dàng (chỉ cần next thôi).
  • Trong gói này mặc định có một GUID để thao tác các câu lệnh trên đó là HeidiSQL. Ta có thể sử dụng nó để thực hiện các truy vấn cơ bản tới cơ sở dữ liệu MySQL hoặc MariaDB.

Về phần DB là xong, để kết nối từ Python tới MariaDB ta cần sử dụng một thư viện để thực hiện kết nối và thực hiện các câu lệnh như Select, Insert, Update, Delete. Vì MariaDB là một phiên bản được fork từ MySQL nên ta có thể sử dụng thư viện mysql-connector.

Trên Anaconda ta có 2 cách để cài đặt thư viện là:

  1. Vào mục Environments, tìm gói đã được Anaconda tập hợp vừa tương thích Python và tương thích với các thư viện khác.
  2. Nếu cách trên không được do một lỗi nào đó hoặc Anaconda chưa hỗ trợ thì ta có thể cài đặt thực tiếp thông qua dòng lệnh. Có thể tham khảo thông qua hướng dẫn: https://enterprise-docs.anaconda.com/en/latest/data-science-workflows/data/mariadb.html

Khi mọi thứ done ta có thể sử dụng đoạn lệnh sau để test kết nối.

import pandas as pd
 import numpy as np
 import matplotlib.pyplot as plt
 import seaborn as sns
 %matplotlib inline
 from urllib.request import urlopen
 from bs4 import BeautifulSoup
 #
 import MySQLdb
 db = MySQLdb.connect(host="127.0.0.1", port=2017, user="root", passwd="test", db="test")
 c = db.cursor()
 a1="https://trituenhantao.info/posts"
 c.execute("SELECT url FROM test")
 d=c.fetchall()
 a2=0
 for url in d:
     #if url.startswith('http://trituenhantao.info'):
         a2=a2+1
         print(f'{a2} URL: {url}')
         print(url)
 print(c.fetchone())

Convert csv sang excel với pandas trên Anaconda

Trong quá trình làm việc, mình rất hay phải thao tác với các file csv, excel, html… vì liên quan đến nhiều các phòng ban và làm việc nhiều với dữ liệu, báo cáo.
Đặc thù hệ thống bên mình sử dụng Oracle, họ đã viết sẵn các thủ tục chỉ có thể xuất ra các file có định dạng là csv và html. Nhưng đối với mọi người thì dùng excel thuận tiện hơn, không chỉ IT mà các phòng khác như kế toán… Thế nên mọi người, trong đó cả mình thường xuyên phải chuyển file csv sang định dạng excel để xử lý.
Để chuyển csv sang excel có nhiều cách:

  • Sử dụng tính năng Load data từ file csv có sẽ trong Excel. Cách này đòi hỏi vài bước để xử lý, nhất là đối với dữ liệu text toàn chữ số dài và Tiếng Việt có dấu.
  • Sử dụng tính năng convert trên mạng, có thể google.

Đa phần mọi người đều phải dùng tính năng của excel vì không thể tùy tiện dùng các tool linh tinh nhất là trên mạng vì tính nhạy cảm của dữ liệu. Thế là mình nghĩ ra việc tự làm tool hoặc script xử lý vấn đề trên cho bản thân. Đơn giản là convert từ csv sang excel.
Ban đầu định dùng .NET vì mình đã triển khai nhiều tool cho công việc. Nhưng hiện mình đang mày mò Machine Learning với Anaconda nên mình nghĩ viết bằng Python xem sao.
Với Python có thư viện pandas xử lý rất tốt về mặt dữ liệu, đặc biệt là dữ liệu với excel và csv. Đối với Anaconda thì pandas là một trong những thư viện mặc định trong đó nên không cần cài đặt gì cả.
Đoạn code rất đơn giản như sau:

import pandas as pd 

data = pd.read_csv("C:/Users/SVPK/Desktop/Extract_warranty_201909.csv",delimiter = ';',prefix = 'T',header = 0)  

# print(data) 

 data.to_excel("C:/Users/SVPK/Desktop/Extract_warranty_201909.xlsx") 

Mình giải thích qua đoạn code trên như sau:
Mục đích sẽ load dữ liệu từ csv lên một biến, sau đó tiến hành ghi nó ra file excel.(Đơn giản vậy thôi)
Các tham số chủ yếu mình đã thử là:

  • delimiter: Mặc định csv nó là dấu ‘,’ nhưng hệ thống mình toàn sử dụng dấu ‘;’ để ngăn cách trong file csv
  • prefix: Đối với file mà không chứ tên cột mà muốn đặt tên cột thì mình để tiền tố này để nó đặt mặc định
  • header: Vì có tên cột với không có tên cột nên thực chất data của mình sẽ bắt đầu từ đâu sẽ do tham số này quyết định.

Từ đây dùng cho mình ok, nhưng nhược điểm khó chuyển cho người khác dùng vì phải cài Anaconda hoặc ít nhất là python và pandas. Nên mình đang nghĩ các cách để dùng như:

  • Tạo 1 thư mục cho mọi người ftp để đẩy file vào. Mình có 1 job quét và xử lý sau đó đưa file kết quả sang 1 thư mục khác để mọi người dùng.
  • Tạo một tính năng trên Tool để mọi người upload lên và tải file kết quả xuống (hoặc nhập email để gửi về)
  • Gửi email đến email của mình. Mình sẽ dùng job trên Pentaho tiến hành tự load email, bóc tách file đính kèm, xử lý và gửi trả lại.

Thôi, tạm thời thế đã, dùng Anaconda để chạy cho riêng mình vậy.

Xóa dấu Tiếng Việt

Trong quá trình làm việc với Oracle trên Toad, mình hay lưu các câu lệnh SQL ra file SQL hoặc biên dịch các package, procedure có chứa các đoạn text có dấu Unicode – cụ thể là Tiếng Việt có dấu. Nhưng mình hay thấy sau khi load file SQL lại lên thì toàn bộ dấu Tiếng Việt bị lỗi, tự nó chuyển sang dấu hỏi. Việc này gây cho mình nhiều lúc bực mình vì bị lỗi hết đoạn text không đọc được, có thể do mình chưa config Toad để có thể phù hợp với Tiếng Việt.

Bình thường mình hay xử lý bằng cách làm thủ công bằng tay chuyển các đoạn text có dấu thành Tiếng Việt không dấu hoặc viết bằng Tiếng Anh. Nhưng như thế là không thuận lợi, mình không thích thế.

Tiện thể mình đang có 1 cái webtool bằng .NET tạo ra các tính năng dành riêng cho mình xử lý các công việc thường ngày. Mình liền xây dựng một tính năng nho nhỏ chuyển 1 đoạn text Tiếng Việt có dấu thành đoạn text Tiếng Việt không dấu.
Tính năng này rất đơn giản, chỉ có 2 ô textbox ở chế độ Multiline và một nút bấm. Nút bấm sẽ tiến hành việc xử lý lấy đoạn text ở textbox 1 tiến hành convert thành không dấu và chuyển sang ô textbox 2.

Mình tách thành một hàm riêng để xử lý như sau:

public static string RemoveUnicode(string text)
         {
             string[] arr1 = new string[] { "á", "à", "ả", "ã", "ạ", "â", "ấ", "ầ", "ẩ", "ẫ", "ậ", "ă", "ắ", "ằ", "ẳ", "ẵ", "ặ",
         "đ",
         "é","è","ẻ","ẽ","ẹ","ê","ế","ề","ể","ễ","ệ",
         "í","ì","ỉ","ĩ","ị",
         "ó","ò","ỏ","õ","ọ","ô","ố","ồ","ổ","ỗ","ộ","ơ","ớ","ờ","ở","ỡ","ợ",
         "ú","ù","ủ","ũ","ụ","ư","ứ","ừ","ử","ữ","ự",
         "ý","ỳ","ỷ","ỹ","ỵ",};
             string[] arr2 = new string[] { "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a",
         "d",
         "e","e","e","e","e","e","e","e","e","e","e",
         "i","i","i","i","i",
         "o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o",
         "u","u","u","u","u","u","u","u","u","u","u",
         "y","y","y","y","y",};
             for (int i = 0; i < arr1.Length; i++)
             {
                 text = text.Replace(arr1[i], arr2[i]);
                 text = text.Replace(arr1[i].ToUpper(), arr2[i].ToUpper());
             }
             return text;
         }

Build lên thế là xong. Mình có thể triển khai ở các ngôn ngữ lập trình khác nhau một cách tương tự.