Article directory
- Implementation
- 21. Package cr as a web service! [Insert picture description here](https://img-blog.csdnimg.cn/186a92259dde470285864efe37c5d2a2.png)
- 22. Use postman for comprehensive testing: simulate the json string entered by the user
- 23. oj_server preparations
- 24. Write the service routing function of oj_server
- 25. Create a file version of the question bank
- 26. Build model code structure
- 27. Write model code 1 (get all questions and get 1 question)
- 28. Write model code 2 (load configuration file)
- 29.model add log
- 30. Use boost split string segmentation
- 31. Write the overall structure of the control module
- 32. Introduce ctemplate to test basic functions
- 33. Write the overall code structure of the view module
- 35. Write a view to obtain the specified topic function
- 36. Write the overall structure of the load balancing module code
- 37. Write load balancer code
- 38. Write judge function 1
- 39. Write judge function 2
- 40. Write judge function 3
- Summarize:
Implementation
20. Introduce the httplib third-party library
Accessing network services, writing sockets by yourself is too slow, so use a third-party library,
Install cpp-httplib
After downloading the third-party library,
use XFTP to import the cpp-httplib library
Copy the httplib.h in the library to the project and use it directly
It is necessary to upgrade the GCC version to a higher version. It is recommended to use gcc 7. It is recommended to use a higher version of gcc. It is recommended to use gcc 7, 8, 9 [If there is no upgrade, cpp-httplib: either compile error or run error.
Baidu search: scl gcc devsettool upgrade gcc
//Install scl
$ sudo yum install centos-release-scl scl-utils-build
//Install a new version of gcc, here you can also replace 7 with 8 or 9, I use 9, You can also install both
$ sudo yum install -y devtoolset-7-gcc devtoolset-7-gcc-c++
$ ls /opt/rh/
//Startup: details, the command line startup is only valid in this session
$ scl enable devtoolset-7 bash
$ gcc -v
The preparations are ready, and the following officially starts.
The environment is not updated, update the gcc version in vscode
if you want this library Use it in your own project, directly include the definition of the library, then Server svr, svr.listen( ) can be used normally, and start the http service; but now there is nothing after starting, so you need to bind some services.
When the user request (the json string in &req) arrives and requests the service (the first parameter) in svr.Get, the content in &resp will be returned
Error: Occasional error, turn off vscode and reopen it
in our project: when the user request (json string in &req) arrives, when requesting the service (the first parameter) in svr.Get, pass our compile_run Generate a json string, and then return the contents of the json string
Create a new wwwroot folder (just for testing, which is equivalent to the root directory of compile_server), and create an index.html file in it.
After having the root directory, calling surver will have obvious effects.
The above is just a test, and we don’t need it for this project. To display the page, you only need to compile and run the json string input by the user, and then output the json string
21. Package cr as a web service
Package a service: the service requested by the user is compile_and_run
22. Use postman for comprehensive testing: simulate the json string entered by the user
At present, no user requests a json string, so first use postman to simulate a user requesting a json string
to run the test
and then start postman
Then you can enter the json string to
send
and continue testing: Infinite loop
Our compile_server needs multi-host deployment, so its port number should be exposed
atoi(argv[1]) is to convert argv[1] to an integer
The compilation service is completed above, and the following is to build a small website
23. oj_server preparations
Essence: Build a small website
> 1. Get the homepage and use the topic list as the
> 2. Edit area page
> 3. Submit the judgment function (compile and run)
Using the MVC design pattern
M: Model, usually a module that interacts with data, for example, adding, deleting, modifying and checking the question bank (file version, MySQL)
V: view, view, usually after getting the data, it is necessary to build a web page, render the content of the web page, and display it to the audience The user's (browser)
C: control, controller, is our core business logic
oj_server is used for load balancing calling compile_server
to upgrade gcc
24. Write the service routing function of oj_server
According to the different needs of users, display different content to users
- Get a list of all topics
- The user needs to obtain the content of the topic according to the topic number
- User submits code and uses our judgment function (1. Test cases for each question 2. compile_and_run)
1. Obtain a list of all topics
2. The user needs to obtain the content of the topic according to the topic number
3. Judgment: The user submits the code and uses our judgment function (1. Test cases for each question 2. compile_and_run)
You can see that there is an oj_server bound to the port number 8080.
Simple check:
But we don’t have a home page, we can write a simple home page
Add a www.root
to set the home page to be in the www.root directory by default
25. Create a file version of the question bank
Design question bank:
First of all, tell us where the questions are
Question number, unique
Title of
the question Difficulty of the
question Description of the question, question face
Time requirement of the question (internal processing) (S)
Space of the topic to be removed (internal processing) (KB)
In addition, when we look for topics in the oj list, only the title of the topic, click to enter the content
Two batches of files constitute
- The first one: questions.list: a list of questions (the content of the questions is not required)
- The second: the description of the topic, the preset code of the topic (header.cpp), and the test case code (tail.cpp).
These two contents are related by the number of the topic
If there is only one question in the questions.list, then there is only one folder named after the question number under the questions folder (questions.list includes the question number, question, difficulty, , time complexity, and space complexity (30M in the figure) ))
Create two new files: file description and default code
Default code:
After the user enters the code, how do you know whether it is correct? Therefore, a test case module is needed, and the new file tail.cpp
can be realized as shown in the figure below
. Therefore, it is finally submitted to The code compiled in the background is a complete code of header.cpp + tail.cpp, let the backend run, and start compiling-running-linking when running, and all the results of running will eventually be output to the stdout file, in the form of json The form returns to me, so it has passed several test cases, and the number of passed test cases is directly returned to the client,
which completes the function of judging
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
class Solution{
public:
bool isPalindrome(int x)
{
//将你的代码写在下面
//code
//code
//code
//code
//code
return true;
}
};
// 下面的代码,我们不想让编译器编译的时候,保留它,而是裁剪掉(g++ -D COMPILER_ONLINE)
// 仅仅是为了让我们设计测试用例的时候,不要报错
#ifndef COMPILER_ONLINE
#include "header.cpp"
#endif
void Test1()
{
// 通过定义临时对象,来完成方法的调用
bool ret = Solution().isPalindrome(121);
if(ret){
std::cout << "通过用例1, 测试121通过 ... OK!" << std::endl;
}
else{
std::cout << "没有通过用例1, 测试的值是: 121" << std::endl;
}
}
void Test2()
{
// 通过定义临时对象,来完成方法的调用
bool ret = Solution().isPalindrome(-10);
if(!ret){
std::cout << "通过用例2, 测试-10通过 ... OK!" << std::endl;
}
else{
std::cout << "没有通过用例2, 测试的值是: -10" << std::endl;
}
}
int main()
{
Test1();
Test2();
return 0;
}
New title:
desc.txt
header.cpp
tail.cpp
added!
The following needs to be completed:
1. Load all the questions
2. Load a single question
26. Build model code structure
Realize with hash map (K:V)
First write a structure of the title
//Save all the data in the undered_map. K: V (question number: topic details)
Load configuration file: find query.list, get header.cpp, tail.cpp, dest.txt in each question
Get a question + get all questions
The following tasks: how Write these three functions:
- LoadQuestionList
- GetAllQuestions
- GetOneQuestion
27. Write model code 1 (get all questions and get 1 question)
1. Get all topics
2. Get a topic
28. Write model code 2 (load configuration file)
Reading files: reading by line
Need a string tool: splitting string
Who should split? Divide this line in the title.
If it is referenced in the model, refer to its namespace.
Add the path of the question bank.
The path of a single question
Read the file
Next, insert the read into the questions structure
29.model add log
Failed to load question bank
Failed to load some questions
30. Use boost split string segmentation
Install the boost library
sudo yum install -y boost-devel //是boost 开发库
boost split
run
without compression ::::::
Delete after testing
to complete string segmentation
31. Write the overall structure of the control module
Help us with logical control
First write a namespace,
what is in the class controller? The control must be able to access each model.
When a user wants to request access to all topics, we should return an html page containing all topics. Therefore, first include the control module in the oj_server.
When the user wants to request access to all topics, get all the data through the control in the oj_server (the model is included in the control), use the control to get all the topics, and then return an html to the user.
So build a function to get all the questions in oj_control
to get a single question
After obtaining the data, how to convert the data into a web page? You need to include the view mode
32. Introduce ctemplate to test basic functions
After obtaining the data, how to convert the data into a web page? Then you need to include the view mode
and then introduce a ctemplate rendering library
https://hub.fastgit.xyz/OlafvdSpek/ctemplate
import library
Method 2: import ctemplate
$ git clone https://gitee.com/mirrors_OlafvdSpek/ctemplate.git
//先进入到 ctemplate 目录下
$ cd ctemplate
$ ./autogen.sh
$ ./configure
$ make //编译
$ make install //安装到系统中
Pay attention to the gcc version
If the installation reports an error, pay attention to using sudo
finish installation:
./autogen.sh
./configure
make //编译
make install //安装到系统中
After installing the library, you can test it
Data rendering:
We need a data dictionary to store key and value
and then need a webpage content to be rendered. We can replace the key in the webpage content with the value corresponding to the key value in the data dictionary. These two are
connected through the ctemplate interface
1. Form a data dictionary
2. Get the rendered web page object
3. Add the data dictionary to the webpage
4. Complete the rendering
How to use it next?
In this webpage, it involves the content of the front end (with some configurations, automatic completion, etc.)
! +table can automatically generate the basic code of the webpage
Next, we need to replace the data that needs to be rendered in the webpage with the content in the data dictionary we just made, so (the
rule of ctemplate is: the key value that needs to be replaced is enclosed by double curly braces )
Next, compile and upgrade the compiler.
Three suffixes are added when compiling, because:
- Using c++11 features
- The ctemplate library is used
- The pthread library is used in the ctemplate library
Original page
rendered! ! ! ! ! Complete the replacement
and then make the rendered view into a view function
33. Write the overall code structure of the view module
How to use view?
First reference the view in the control
Get all topics and form a web page
Obtain the specified topic and form a webpage
. After adding it, you need to write a view class. There are two interfaces in it, one is AllExpandHtml, and the other is GetOneQuestion.
In the list of questions, only need to display: question number, question, difficulty. It
is recommended to use a table to display the list of questions.
Test:
first make , and then run
to search for html tutorials to see how to write html tables
Create two new webpages, which will be used for OJ_view rendering later.
1. List of all questions
First build a root dictionary root, then build a sub-dictionary questions_list, and then add data to the sub-dictionary
1. Form a path
2. Form a data dictionary
3. Get rendered html
4. Execute rendering
Add a jump link
Problem: Not in order, a bit messy, sort it later
35. Write a view to obtain the specified topic function
What I want to achieve next: click on a question to jump
1. Form a path
2. Simply write one_question
3. Render in view
4. Add a jump in all_question, that is, when you click on a question in the question list, you can jump to a single question
and jump to this request service: request question/a question number
Test:
36. Write the overall structure of the load balancing module code
Implement a judgment function according to the control controller
and then design the next function: load balancing
Create a new file: a list of hosts that can provide services to us
How to design load balancing?
Load balancing module:
The path of the host that provides the service
All hosts can be loaded at startup
Load-balanced code structure:
37. Write load balancer code
The first function: load the configuration file
If all configuration files are loaded in, all hosts are already in machines, and all host subscripts are in online. 2.
Smart selection
If you want to get the host number and more detailed information of the host,
you may face countless host accesses , so it needs to be locked. A total of two locks have been added, one is a big lock: LoadBlance; the other is to lock each host:
after having the lock,
error: no online host
Through traversal, find all machines with the smallest load.
The load may increase or decrease. Write the corresponding function.
Obtaining the host load does not make much sense, just to unify the interface
The above is completed: get the load situation
The host has been given, and the load balancing algorithm has also been given. The next step is to write Judge.
38. Write judge function 1
0. According to the topic number, directly get the corresponding topic details
1. deserialize in_json, get the id of the title, get the source code submitted by the user, input
2. Reassemble user code + test case code to form new code
39. Write judge function 2
3. Choose the host with the lowest load (error handling)
// Rule: keep selecting until the host is available, otherwise, all hang up
4. Then initiate an http request and get the result
When requested, update the load: load increments; load decreases
40. Write judge function 3
After the request is successful, the code uploaded by the user will be sent to the backend server for compilation and operation.
After the request fails, the host will be offline
When offline, someone may come to request the host, so if you add a lock when offline, no one will request it.
Offline host
View the current online host list and offline host list
Summarize:
Realized the host machine that can provide us with load balancing function (that is, one machine corresponds to one backend service), you can deploy three compilation services on one machine, then it corresponds to three machines, and you can deploy on 100 machines in the future Deploy 200 compilation services on the Internet, two for each machine, then you have 200 machines, so it is a logical concept.
Then, what it provides is to update its own load, reduce its own load, and obtain its own load.
Next, what our load balancer loadBlance does is: according to the configuration file, all the hosts and ports we have pre-configured are brought in. , After getting it in, push him into the machines.
After startup, all our hosts have been loaded into our memory or our load balancing module, and by default all hosts are online at startup. So one of the functions that the subsequent load balancer will provide us is intelligent host selection (smartchoice). When selecting, others may be doing offline hosts or doing something, but as long as we lock it. In smart selection, polling is used to find the host with the least load, and then hash, that is, the ID method, is used to index our target host.
After selecting the host, we can support our subsequent Judge: first obtain the topic, then deserialize the json originally requested by our customer (obtain the id of the topic, source code), after deserialization, rebuild the json string, There is a very important process in it, which is to splice the user's code with our own test case code (without this step, the question cannot be judged). Next, build all the above content into a json string for later use
Next, perform error handling on the selected host with the lowest load: keep selecting until the host is available, otherwise, all hang up.
As long as the host is selected successfully, a machine makes a request, and then requests the backend through the post method. After the request is successful, it will automatically help us execute the service we wrote, compile-link-run, and form the result into json Give us the string, after giving it to us, if there is no problem with the request and the status code is equal to 200, then we will return out——json, the load will decrease, then the compilation service will succeed, and then break; otherwise, after the compilation fails (the status code is not 200), Just re-select.
If you really can’t find the host, check all the online hosts to see which hosts are online and which are offline
All about the load balancing module is done! ! ! ! ! ! ! ! ! ! !