Mọi người cho em hỏi về vấn đề scale server với ứng dụng Laravel với ạ
Hướng bạn làm như vậy mình nghĩ là ổn đó. Bạn nên scale riêng từng loại:
- Web cần nhiều thì scale thêm nhiều process hoặc thêm server chạy web (fpm only, không queue, cron)
- Nếu chỉ chạy queue ở server ban đầu mà bạn thấy không đáp ứng được thì scale tiếp queue:
- Tăng process của worker lên
- Tăng số worker lên, chia nhỏ thành nhiều queue riêng biệt như queue cho mails, default... -> chia queue thì code cũng phải sửa để chỉ định dispatch job vào từng queue cụ thể.
Có thể là còn nhiều giải pháp nữa nhưng ở trên là những giải pháp đơn giản nhất để bạn scale Laravel mà mình vừa note ra. Bạn tham khảo nhé.
Query model sử dụng WhereLike
Cái $name
em thử đổi lại thành số thôi.
Sẽ là 5
thay vì Street#5
. Sau đó thì thử như này xem được không:
$street = Street::where('name', 'LIKE', "Street#%{$name}%")->get();
Ajax trong laravel
Bạn làm create như nào thì edit cũng tương tự như vậy. Vẫn tiếp tục dùng FormData
để gói dữ liệu gửi lên server. Chỉ khác là lúc render các trường trong form thì bạn gán value đã tồn tại (sau khi create) cho nó qua thuộc tính value
. Nếu render form bằng laravel thì truyền value như này:
Form::email($name, $value = $user->email, $attributes = array());
Đưa biến javascript vào trong asset_path
Chuyển thế thì bị sai logic rồi @devil_boom_129 , vì code cũ người ta chỉ tạo image kho có value là path1
và path2
thôi
Cách Khác phục lỗi 302 khi up code lên host !
302 là status code thể hiện trạng thái rằng server muốn bạn chuyển hướng tới một trang khác thay thế. Bạn thử kiểm tra vấn đề về https hoặc logic trong code những đoạn xử lý redirect xem sao, có bug không?
Chẳng hạn bug kiểu như:
- Truy cập http://localhost/admin
- Server rediect về http://localhost/admin/login.php
- Cấu hình tự redirect trên server sai dẫn tới trang http://localhost/admin/login.php lại redirect về http://localhost/admin thay vì https://localhost/admin/login.php dẫn tới là lại quay về step 1 và bị lặp đi lặp lại 3 step này.
Bạn thử xem sao nhé.
Tối ưu hóa câu truy vẫn trong laravel
public function getDevicesService(Request $request, $device)
{
$pageSize = _clamp($request->per_page, 20, 100) // clamp $pageSize, min: 20, max: 100 -> should add _clamp helper
$users = User::with('devices')->paginate($pageSize); // eager loading user devices
// Your logic
return $users;
}
Optimize code cho chủ thớt một tẹo trước. Cho mình hỏi TDevice
và cái $item_device
device có quan hệ như nào với nhau vậy?
Trong vòng for chủ thớt không query như kia sẽ dẫn tới n+1 query. Nên dùng eager loading giống cái devices
mình viết ở trên nhé.
Multype-auth trong laravel
- Nếu chủ thớt chỉ muốn là giới hạn admin vs user thường ở một số trang thôi thì có thể dùng middleware của laravel cho trang cần phân quyền là được rồi chứ không cần phức tạp thêm đâu. Nếu đã có cơ sở để phân biệt admin, user rồi thì không phải thêm bảng gì hết nữa cả.
class AdminOnly
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$user = $request->user();
if (!$user || $user->isAdmin !== true) {
return abort(403, 'Permission Denied');
}
return $next($request);
}
}
Sau đó thì dùng middleware này khi khai báo route:
Route::get('/private-page', 'Controller@action', ['middleware' => 'admin']);
Route::group(['prefix' => '/admin', 'middleware' => 'admin'], function () {
Route::get('/dashboard', ...);
});
- Không thích dùng middleware như kia thì dùng Gate/Policy là chuẩn bài rồi
[SQL] Cho em hỏi về ráng khóa chính khóa ngoại trong sql
- Một field được set làm khóa chính cho table để định danh duy nhất cho một record, giá trị của field đấy sẽ không được trùng lặp. Nên thường là field đấy sẽ là Number và tự động tăng. Và thường là ID của record.
- Khóa ngoại: Dùng để thể hiện mỗi quan hệ giữa các thực thể trong hệ quản trị cơ sở dữ liệu quan hệ. Ví dụ như: Một student chỉ thuộc một lớp học, muốn biết student nào học lớp nào sau khi lưu vào database thì mình cần biểu diễn quan hệ này bằng cách lưu thêm
ID
của lớp học(class_id)
vào bảngStudents
. Khi đó thì mỗi record sẽ có 1 fieldclass_id
để xác định, hay trong trường hợp này anh em hay truyền miệng nhau câu thần trú là lấy khóa chính làm khóa ngoại. Tùy vào mối quan hệ kiểu 1-n, n-n mà khóa ngoại sẽ được lưu ở những cách khác nhau nhé bạn.
Sử dụng khóa ngoại sẽ giúp bạn tiện truy vấn ở những câu truy vấn phức tạp trong thực tế và tạo ràng buộc quan hệ giữa các thực thế trong hệ quản trị cơ sở dữ liệu quan hệ. Chẳng hạn như bạn sẽ không thể thực hiện query để xóa Lớp học khi trong database, lớp học đã có học sinh (xác định thông qua khóa ngoại).
componentDidMount
Lần đầu chưa có dữ liệu thì bạn có thể đặt default value là null, nếu null thì sẽ chưa render component sử dụng data mà hiển thị một compomnent Loading thay thế, hoặc hiển thị placeholder như Skeleton của Ant Design chẳng hạn để web không bị lỗi khi chưa có dữ liệu.
Ngoài ra, nếu dùng Next.js thì bạn có thể fetchData trong getInitialProps
, nó support promise nên bạn có thể fetch data ở đây xong rồi component mới render. Khi đó ở lần đầu tiên render thì data đã có trong props rồi và bạn không phải fetch data ở componentDidMount
nữa.
Thư viện chuyển mã HTML thành text Trong react-native hoặc js
Mình thấy trên NPM có nhiều lib lắm nè bạn:
https://www.npmjs.com/search?q=html to text
Bạn xem cái nào nhẹ thì dùng cũng được.
Hỏi về series học angular trên viblo.
Viblo hiện tại đang chưa có search theo series. Bạn co thể vào trong trang này tham khảo, mình thấy có nhiều lắm, bạn thử vào xem sao nhé. https://viblo.asia/tags/angularjs/series
Deploy ứng dụng nodejs lên vps google bị lỗi 502
Việc lỗi 502 là do Cloudflare không lấy được response từ web server của bạn. Nguyên nhân thì có khá nhiều, mình thử list một vài case để bạn check thử:
- Web server cấu hình sai, tức bản thân cái web còn chưa chạy được trên server => Bạn ssh lên server rồi thử tạo một cái request tới localhost thử
curl http://localhost
-
Node app đang listen sai port. => Kiểm tra nếu app đang listen port 3000 thì cần tạo proxy bằng nginx hoặc apache2... để forward request từ port 80/443 về 3000
-
VPS chưa open port 80, 433 hoặc port 3000 => Cần check lại trong fireware của VPS trên Google Cloud
Hy vọng một vài case trên sẽ giúp ích được bạn.
Hỏi về việc dùng markdown để cho phép người dùng đăng bài
Lúc lưu contents
vào database bạn lưu cả cú pháp Markdown thì lúc render ra client bạn phải thêm một bước render contents
từ Markdown về thành HTML nữa nhé. Dùng express thì có thể sử dụng markdown-it
để render:
// node.js, "classic" way:
var MarkdownIt = require('markdown-it'),
md = new MarkdownIt();
var result = md.render('# markdown-it rulezz!');
Laravel: Update data vào mảng cách tối ưu nhất
@thanhminh1998 Nếu lưu vào dữ liệu gửi lên vào một bảng thì sau bạn nhỉ? Mỗi lần app gửi dữ liệu lên server thì mình lưu thành một row mới trong database. VD:
id | user_id | type | json_value | created_at |
---|---|---|---|---|
1 | 1 | view_post_tracking | { "postID": 1, "title": "First post" } | 2020-02-21 04:00:00 |
2 | 1 | view_post_tracking | { "postID": 2, "title": "Sencond post" } | 2020-02-21 05:00:00 |
3 | 1 | view_post_tracking | { "postID": 3, "title": "Third post" } | 2020-02-21 06:00:00 |
4 | 1 | open_link_tracking | { "postID": 2, "title": "Second post" } | 2020-02-21 07:00:00 |
Lúc nào bạn cần dùng thì query tất cả các row trong database ra.
SELECT logs.*
FROM logs
WHERE user_id = 1 AND type = 'view_post_tracking'
[VIBLO] TEAM VIBLO KHI NÀO RA CHỨC NĂNG GOM BÀI VIẾT VÀO CÁC SERIES?
Để tạo series bạn làm các bước sau theo hình nhé:
Thực sự mình thấy vẫn mơ hồ về asynchronous (async-await) trong Javascript
1. Async/await cũng giống như promise, là non-blocking
Có lẽ là do câu chữ nên có thể làm bạn hơi khó hiểu. Mình nghĩ ý tác giả viết thế là vì một async function
sẽ return một Promise
nên khi các hàm khác dùng nó thì sẽ giống như là dùng Promise
. Mình cho ví dụ:
const sayHello = async () => {
console.log('Hello')
}
// Example 1:
console.log(sayHello())
> Promise
// Example 2:
sayHello().then(() => {
console.log('Hi!')
})
Như vậy thì một async function
sẽ chính là một Promise
- tức nếu xét cả cái async function
thì nó vẫn là một function bất đồng bộ. Tuy nhiên nội dung bên trong async function
thì đúng như bạn đang nghĩ, qua từ khóa await
, nó sẽ khiến cho code bên trong async function
chạy từ trên xuống dưới như ý đồ bạn mong muốn. Tóm lại là chúng ta đang dùng bất đồng bộ để khử bất đồng bộ.
2. Async/await làm cho code bất đồng bộ nhìn và chạy gần giống như code đồng bộ.
Tác giả nói đúng đó bạn, bản chất thì cái code bên trong cái async function
nó vẫn là code bất đồng bộ. Tuy nhiên cơ chế xử lý khác hơn một chút do trong ES6 có thêm một khái niệm gọi chung là Job Queue - một tầng phía trên của Event Loop Queue. Hiểu ngắn gọn thì trên ES6 implement thêm một cái Queue nữa để làm cho code trở nên chạy đồng bộ khi dùng async/await
. Mình giải thích tới đây thôi bạn tìm hiểu thêm về Event Loop, Job Queue trên ES6 nhé.
Angularjs cached state sau khi compile assets
Thông thường khi build production thì mình hay config webpack để output ra các file kèm theo hash
của content. Kiểu như này:
module.exports = {
//...
output: {
filename: '[name].[hash].bundle.js'
}
};
Khi đó tên của mỗi file sẽ có một cái mã hash
:
- Nếu content của file đó ko sửa đổi -> hash vẫn sẽ giữ nguyên -> file được cache
- Nếu content của file bị sửa đổi -> hash của content sẽ thay đổi -> tên file khác với version trước -> hạn chế được việc bị cache.
Ngoài ra cũng có một cách khác mà mọi người hay dùng đó là thêm queryString
vào các đường link load css, js kiểu như này:
https://viblo.asia/assets/style.css?ver=1.0.2-beta.10
Khi nối thêm version thay đổi thì đường link có query string mới nên cũng sẽ hạn chế được việc bị cache.
Cách chuyển blog wordpress vào trong một website khác ??
Mặc định thì Wordpress sẽ chạy với domain hoặc địa chỉ IP với root URL (/
). Theo mình hiểu thì bạn đang muốn deploy web Wordpress của bạn sau path prefix là /blog
. Bạn thử thêm 2 dòng config sau nữa xem sao:
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/blog');
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/blog');
Mình thấy bạn đang thêm prefix bằng cách để code trong sub folder là /var/www/html/blog
. Đây cũng là một cách rất đơn giản, nếu dùng cách này thì bạn ko cần phải dùng .htaccess
để rewrite lại URL nữa.
Tên công nghệ/ giải pháp dùng để listener sự kiện từ Backend trên Web Browser Client?
Về mặt technical thì gọi là Web Socket / Socket.io là đúng rồi đấy bạn. Bạn tham khỏa thêm comment của bác @johansirius ở phía bên dưới, mình thấy bác ý nói đúng rồi đấy:
Giải pháp phổ biến nhất là dùng Websocket, ứng dụng trên di động duy trì kênh kết nối đến backend, ngay khi hoàn thành đơn hàng, mobile sẽ phát một sự kiện và backend chuyển trang. Do là trang TMĐT lưu lượng rất lớn nên họ thường dùng Kafka hay RabbitMQ.
Theo đó thì bạn có một số technical để áp dụng vào hệ thống như:
- Web socket / socket.io
- Pusher
- Kafka
- RabbitMQ
Nếu website của bạn là website nhỏ thì bạn cứ socket.io mà dùng nhé.
Vài vấn đề về SSL
-
Free SSL, có thể dùng Cloudflare, ổn định rồi. Viblo cũng đang dùng SSL của Cloudflare kìa bạn . Ngoài ra, có Let's Encrypt, cho mình Free SSL nhưng phải renew lại cerkey sau mỗi 3 tháng. Nếu dùng Cloudflare thì mình không phải quan tâm tới vấn đề renew vì Cloudflare lo cho mình. Còn nếu dùng Let's Encrypt thì có thể cài thêm Cerbot vào server. Đây là tool hỗ trợ tạo key từ Let's Encrypt, tự động renew, tự generate config với web server như Apache, Ngĩnx, HAProxy, Plesk.
-
Về login với Facebook thì đúng là phải https mới chạy. Thường để test dưới local thì bạn dùng self-signed key. Tức là bạn tự generate key rồi dùng nó để enable https.