В этом документе описывается, как использовать API-интерфейс для подключения к MatrixGate и обеспечения высокоскоростного импорта данных.
MatrixGate предоставляет внешнему миру HTTP API, позволяя различным языкам программирования импортировать данные в базу данных YMatrix через HTTP-интерфейс. Ниже приведены формат протокола и коды ответов HTTP MatrixGate.
Формат протокола HTTP MatrixGate
| Тип протокола | Формат протокола | Назначение и примеры |
|---|---|---|
| URL | http://\ |
Указание URL-адреса подключения к mxgate |
| PATH | / | В настоящее время поддерживается только /, все, что следует после /, игнорируется |
| HTTP-метод | POST | Поддерживается только POST для загрузки данных |
| HTTP-заголовок | Content-Encoding: gzip | Поддерживается сжатие содержимого тела запроса gzip |
| Content-Type: text/plain | Поддерживается тип text/plain | |
| Тело HTTP | SchemaName.TableName Timestamp|ID|C1|C2|..|Cn |
Формат тела: первая строка — целевая таблица для загрузки данных. Имя схемы (SchemaName) можно опустить, по умолчанию используется Public. Имя таблицы (TableName) обязательно. Начиная со второй строки — строки с временными данными. Каждая строка соответствует одной строке целевой таблицы. Колонки разделяются символом |, строки — \n. Первое поле каждой строки — временная метка (timestamp), формат UNIX-времени с точностью до секунд (см. описание параметра --time-format). Второе поле — TagID (целое число). С третьего поля и до конца строки следуют значения столбцов, соответствующих целевой таблице. Рекомендуется, чтобы DDL-определение целевой таблицы также следовало порядку столбцов (Timestamp, TagID, C1, C2,…, Cn). |
Коды ответов HTTP MatrixGate
| Код ответа | Значение кода ответа | Примечания |
|---|---|---|
| 200 | StatusOK | Часть данных имеет неверный формат; в теле ответа будет указан номер ошибочной строки и сообщение об ошибке, например:At line: 2missing data for column "c3" |
| 204 | StatusNoContent | Данные успешно загружены в MatrixGate |
| 400 | StatusBadRequest | Ошибка запроса данных: неверный формат тела POST, отсутствие целевой таблицы, несоответствие формата сжатия данным в заголовке HTTP и т.д. |
| 405 | StatusMethodNotAllowed | Запрос не является POST |
| 408 | StatusTimeout | Превышено время ожидания запроса |
| 500 | StatusIntervalServerError | Ошибка базы данных, не удалось загрузить данные; в теле ответа содержится подробная информация об ошибке |
| 503 | StatusServiceUnavailable | MatrixGate отклоняет запросы, например, при превышении максимального количества подключений или при завершении работы MatrixGate |
testtable в базе данных demo.=# CREATE TABLE testtable (
time TIMESTAMP WITH TIME ZONE,
tagid INT,
c1 INT,
c2 INT,
c3 INT
)USING MARS3
DISTRIBUTED BY (tagid)
ORDER BY (time,tagid);
mxgate.conf.$ mxgate config --db-database testdb \
--db-master-host localhost \
--db-master-port 5432 \
--db-user mxadmin \
--db-password 123123 \
--target public.testtable \
--format csv \
--time-format unix-second \
--delimiter '|' \
--parallel 256 \
--stream-prepared 3 \
--interval 250 \
--transform plain \
> mxgate.conf
data.txt:$ vi data.txt
public.testtable
1603777821|1|101|201|301
1603777822|2|102|202|302
1603777823|3|103|203|303
mxgate.conf.$ mxgate --config mxgate.conf
$ curl http://localhost:8086/ -X POST -H 'Content-Type: text/plain' --data-binary "@data.txt"
demo=# SELECT extract(epoch FROM "time"), * FROM testtable;
date_part | time | tagid | c1 | c2 | c3
----------------------------------------------------------------------------------------------------------------------------------
1603777821 | 2020-10-27 13:50:21+08 | 1 | 101 | 201 | 301
1603777822 | 2020-10-27 13:50:22+08 | 2 | 102 | 202 | 302
1603777823 | 2020-10-27 13:50:23+08 | 3 | 103 | 203 | 303
(3 rows)
SDK (комплект разработки программного обеспечения) — это набор инструментов, позволяющий разработчикам сосредоточиться на бизнес-логике, избавляя их от необходимости реализовывать вспомогательные функции, что значительно повышает эффективность и удобство разработки.
Вы можете подключить JAR-пакет SDK одним из следующих способов:
(1). Получить напрямую из удалённого репозитория Maven
(2). Получить напрямую из удалённого репозитория Gradle
(3). Вручную скачать JAR-файл локально и затем импортировать его
Примечание! Выберите любой из перечисленных способов. Рекомендуется использовать (1) или (2) — подключение SDK напрямую из удалённых репозиториев Maven или Gradle, так как это эффективно и удобно. По способу (3) см. MatrixGate FAQ: 21. Рекомендуется выполнить поиск по ключевому слову
JAVA SDK, поскольку этот способ используется редко, здесь он подробно не рассматривается.
(1). Вызов удалённого репозитория Maven для автоматической загрузки пакетов SDK
Настройте следующие зависимости в файле pom.xml вашего Java-проекта.
<dependencies>
<dependency>
<groupId>cn.ymatrix</groupId>
<artifactId>mxgate-sdk-java</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
(2). Использование удалённого репозитория Gradle для подключения зависимостей SDK
repositories {
mavenCentral()
}
dependencies {
implementation 'cn.ymatrix:mxgate-sdk-java:1.0.20'
}
YMatrix поддерживает запись данных через gRPC и HTTP. Подробности ниже:
Примечание! Необходимо использовать версию YMatrix, поддерживающую gRPC, то есть 4.6.1 и выше.
Создайте файл конфигурации mxgate mxgate_grpc.conf на Master-узле и запустите mxgate.
Примечание! Перед использованием mxgate необходимо предварительно создать таблицы в базе данных. В примере хост Master — mdw, база данных —
demo, таблица данных —test_table_transfer.
Код следующий:
# Create mxgate config file
[mxadmin@mdw ~]$ mxgate config \
--source grpc \
--db-database demo \
--target public.test_table_transfer \
--time-format raw \
--grpc-port 8087 \
--format csv \
> mxgate_grpc.conf
# Start mxgate
[mxadmin@mdw ~]$ mxgate start --config mxgate_grpc.conf
Как показано в примере, для записи данных в mxgate с помощью SDK необходимо указать, что параметр source в mxgate — grpc, а format — csv. Кроме того, поскольку SDK должен знать, куда записывать данные, необходимо указать номер порта grpc-port в конфигурационном файле (в примере — 8087).
Примечание! При запуске mxgate через HTTP всё равно необходимо указывать номер порта gRPC mxgate, потому что SDK по-прежнему получает метаинформацию о таблицах базы данных из mxgate по протоколу gRPC, но способ записи данных переключается на HTTP.
Создайте файл конфигурации mxgate_http.conf на Master-узле и запустите mxgate. В примере имя хоста Master — mdw, код следующий:
# Create the mxgate config file.
[mxadmin@mdw ~]$ mxgate config \
--source http \
--db-database demo \
--target public.test_table_transfer \
--time-format raw \
--grpc-port 8087 \
--format csv \
> mxgate_http.conf
# Start mxgate
[mxadmin@mdw ~]$ mxgate start --config mxgate_http.conf
На этом этапе рассматриваются два метода передачи: асинхронный и синхронный. Выберите подходящий в зависимости от ваших потребностей.
Структура примера таблицы:
Partitioned table "public.test_table_transfer"
Column | Type | Collation | Nullable | Default
--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ts | timestamp without time zone | | |
tag | integer | | not null |
c1 | double precision | | |
c2 | double precision | | |
c3 | double precision | | |
c4 | double precision | | |
c5 | text | | |
c6 | text | | |
c7 | text | | |
c8 | text | | |
Partition key: RANGE (ts)
Сначала выполните глобальную инициализацию:
// Set the log level, default INFO.
MxLogger.loggerLevel(LoggerLevel.INFO);
// The log will be output to stdout by default. If you do not want to output, you can pass false in the following API.
MxLogger.enableStdout(true);
// The default log file path and naming format of SDK is /tmp/mxgate_sdk_java_2022-08-26_133403.log,
// Users can customize the file path and file name of the output log file.
MxLogger.writeToFile("/tmp/mxgate_sdk_java.log");
Асинхронная отправка добавляет кортеж (Tuple) в очередь внутри SDK, после чего данные отправляются по асинхронному HTTP-запросу.
Сначала нужно запустить MxBuilder, который работает в режиме одиночки (singleton) и является глобально уникальным.
Примечание! MxBuilder создаётся только один раз в проекте. Соответствующую конфигурацию можно выполнить до инициализации MxBuilder.
MxBuilder builder = MxBuilder.newBuilder() .withDropAll(false) // If used for testing, set to true to drop data instead of sending to mxgate; set to false to send data to mxgate .withCacheCapacity(100000) // Size of the queue for temporarily storing tuples in batches .withCacheEnqueueTimeout(2000) // Timeout for tuples to be enqueued if the queue is full. Throws IllegalStateException if exceeded .withConcurrency(10) // Number of threads writing data to mxgate concurrently .withRequestTimeoutMillis(3000) // Timeout for each data write request (in milliseconds) .withMaxRetryAttempts(3) // Number of retries for each write request if an issue occurs .withRetryWaitDurationMillis(3000) // Interval between retries (currently fixed) .withRequestType(RequestType.WithHTTP) // SDK supports sending data to mxgate via HTTP and gRPC. Corresponding configurations are: RequestType.WithHTTP, RequestType.WithGRPC .withCircuitBreaker() // Use the built - in circuit breaker. If the failure rate or slow request rate reaches the threshold, it will be activated. After activation, data sending to mxgate will be paused for 30 seconds, and tuples cannot be appended .withMinimumNumberOfCalls(1) // Minimum number of calls for the circuit breaker to take effect (must be >= 1, default is 10) .withSlidingWindowSize(10) // Size of the sliding window for calculating the failure rate (must be >= 1, default is 100) .withFailureRateThreshold(60.0f) // Failure rate threshold (must be >0 and <= 100). If the failure rate reaches this threshold, the circuit breaker will be activated .withSlowCallDurationThresholdMillis(1000) // Threshold for slow request duration (milliseconds). Requests exceeding this duration are considered slow (note that this duration should be less than the request timeout) .withSlowCallRateThreshold(80.0f) // Slow request rate threshold. If the slow request rate reaches this threshold, the circuit breaker will be activated // .withRequestAsync(true) // Uncomment this line to enable asynchronous mode for sending data to mxgate (optional) // .withConcurrency(20) // Typically, asynchronous mode only requires tens of concurrency to achieve the same or even higher throughput as synchronous mode (optional) // MxBuilder's builder pattern has added the following API to adjust the concurrency of CSV parallel transformation (at the MxClient Group level) // .withCSVConstructionParallel(100) // (Supported from v1.1.0, uncomment this line to use) .build(); // MxBuilder has added a singleton API. After MxBuilder is successfully built, you can obtain the globally unique singleton instance of MxBuilder at any location using the following API (supported from v1.1.2) // MxBuilder.instance(); // (Supported from v1.1.2, uncomment this line to use) // builder.getTupleCacheSize(); // Uncomment this line to get the number of remaining Tuples in the SDK's internal Tuple cache in real - time (optional)Метод connect объекта Builder принимает четыре параметра: (1). Имя хоста (IP-адрес) и номер порта процесса mxgate, предоставляющего сервис для приёма данных и метаинформации о таблицах базы данных.
Например, для HTTP-метода этоhttp://localhost:8086/; для gRPC —localhost:8087.
(2). Схема (schema).
(3). Имя таблицы.
(4). Callback. Если подключение Builder к mxgate прошло успешно, вызывается метод onSuccess и возвращается экземпляр MxClient для записи данных. При неудаче вызывается onFailure, а failureMsg содержит причину ошибки.
Код следующий. Не забудьте заменить номер порта, имя схемы и имя таблицы на фактические значения.
// Asynchronous method (this feature is supported starting from v1.0.13)
builder.connect("http://localhost:8086/", "localhost:8087", "public", "test_table", new ConnectionListener() {
@Override
public void onSuccess(MxClient client) {
sendData(client);
}
@Override
public void onFailure(String failureMsg) {
}
});
Через функцию обратного вызова onSuccess() интерфейса ConnectionListener можно получить экземпляр MxClient, а затем использовать API MxClient для записи данных в mxgate.
// Synchronization method (this feature is supported starting from v1.0.13)
MxClient client = builder.connect(httpHost, gRPCHost, schema, table);
/*
* v1.1.0 improves the scalability of MxClient, and MxBuilder provides several new APIs. The MxClient obtained through this API belongs to a MxClient Group.
* You can freely define the concurrency parameters of MxClient Group Number, Tuples cache capability, and TuplesConsumer through these APIs.
* (This feature is supported starting from v1.1.0)
*/
// MxClient client = builder.connectWithGroup(dataSendingHost, metadataHost, schema, table, 10);
// MxClient client = builder.connectWithGroup(dataSendingHost, metadataHost, schema, table, 1, 1000, 3000, 10);// (This function starts with v1.1.0, if you use to remove the comment content of this line)
/*
* For APIs starting with skip, the process of connecting to back-end services to obtain database table meta information will be skipped when calling.
* This type of MxClient can only obtain lightweight Tuples through generateEmptyTupleLite().
* (This feature is supported starting from v1.1.0)
*/
// MxClient client = mxBuilder.skipConnectWithGroup(dataSendingHost, metadataHost, schema, table, delimiter, 1);
// MxClient client = mxBuilder.skipConnectWithGroup(dataSendingHost, metadataHost, schema, table, delimiter, 1, 1000, 3000, 1);
Примечание! MxClient потокобезопасен, однако при использовании в многопоточной среде для достижения оптимальной производительности рекомендуется создавать отдельный экземпляр MxClient в каждом потоке, то есть возвращать несколько экземпляров MxClient через несколько вызовов connect в MxBuilder.
private void sendData(MxClient client) { if (client != null) { /* * MxClient will accumulate a batch of Tuples as a micro batch and send them to mxgate. * This API sets the waiting time accumulated for each microbatch, with a default of 2000 million seconds. * That is, each 2s will try to send a batch of data to mxgate if the 2s time period is * No data is written, no sending */ client.withIntervalToFlushMillis(5000);
/*
* Set how many Tuple bytes accumulated to be sent as a microbatch, even if the time has not been reached
* The set flush interval, the accumulated micro-batch bytes will also be sent if it reaches the number of micro-batch bytes.
* The time of flush interval has reached, and the number of bytes that are not accumulated enough to be set will also be sent
*/
client.withEnoughBytesToFlush(500);
/*
* Compared withEnoughBytesToFlush, when appendTuple
* Performance is improved because it avoids calculating the number of bytes.
* Depending on the specific use scenario, if withEnoughBytesToFlush
* It can also meet the performance requirements, so each flush, the data volume will be more uniform.
* withEnoughLinesToFlush will have higher priority than withEnoughBytesToFlush
*/
client.withEnoughLinesToFlush(10000);
/*
* MxClient has added the following API to adjust the number of Tuples for each CSV conversion subtask.
* For example, there are 10,000 Tuples in Flush at a time. Set BatchSize = 2000 through the following API.
* Then the CSV conversion of these 10,000 Tuples will be divided into 5 subtasks, each subtask handles 2,000 Tuples and executes concurrently.
* (This feature is supported starting from v1.1.0)
*/
client.withCSVConstructionBatchSize(2000);
/*
* Each MxClient has a private object pool.
* When using it, you need to set the size of the object pool according to the number of Tuples in each MxClient flush.
*/
// client.useTuplesPool(poolSize);
/*
* MxClient supports compression and needs to be used with mxgate v4.7.6 and higher
*/
// client.withCompress();
/*
* For HTTP requests, you can not use base64 encoding, and gRPC needs to do base64 encoding
*/
// client.withBase64Encode4Compress();
/*
* MxClient can register a DataPostListener, and the success and failure of each batch of data are sent.
* They will all callback in onSuccess and onFailure. You can understand which Tuple writes succeed and which Tuple writes fail
*/
client.registerDataPostListener(new DataPostListener() {
@Override
public void onSuccess(Result result) {
System.out.println(CUSTOMER_LOG_TAG + "Send tuples success: " + result.getMsg());
System.out.println(CUSTOMER_LOG_TAG + "Succeed lines onSuccess callback " + result.getSucceedLines());
}
@Override
public void onFailure(Result result) {
/*
* result.getErrorTuplesMap() key-value pair containing the line of error and the cause of the error Tuple -> String
* Key is the wrong line, value is the wrong reason
*/
for (Map.Entry<Tuple, String> entry : result.getErrorTuplesMap().entrySet()) {
l.error(CUSTOMER_LOG_TAG + "error tuple of table={}, tuple={}, reason={}", entry.getKey().getTableName(), entry.getKey(), entry.getValue());
for (Column c : entry.getKey().getColumns()) {
l.error(CUSTOMER_LOG_TAG + "error entry columns {} = {}", c.getColumnName(), c.getValue());
}
}
System.out.println(result.getSuccessLines());
}
});
Возвращает пустой объект Tuple, который можно заполнить с помощью API generateEmptyTuple объекта MxClinet.
Tuple tuple1 = client.generateEmptyTuple(); Tuple tuple2 = client.generateEmptyTuple();
Заполняет пустой Tuple парами «ключ → значение». Ключ — имя столбца таблицы базы данных; значение — соответствующее значение поля. Если некоторые поля могут быть null или имеют значения по умолчанию, вы можете не указывать их значения — SDK автоматически заполнит значения по умолчанию или оставит пустыми.
Метаинформация о таблицах базы данных, полученная через этот API, больше не хранится внутри Tuple. Это более лёгкая структура. Поэтому при вызове MxClient.appendTuple() для добавления в MxClient исключается проверка легитимности данных Tuple на основе метаинформации таблицы базы данных, что позволяет максимально быстро отправлять данные.
// Tuple tuple = client.generateEmptyTupleLite();// (This function starts with v1.1.0, if you use it to remove the comment content of this line)
>***Примечание!***
При добавлении столбцов в такой лёгкий Tuple необходимо вручную поддерживать порядок пар `addColumn() key -> value`, чтобы он соответствовал порядку столбцов в таблице базы данных.
Например, порядок столбцов в таблице данных:
Column | Type | Collation | Nullable | Default --------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ts | timestamp without time zone | | | tag | integer | | not null | c1 | double precision | | | c2 | double precision | | | c3 | double precision | | | c4 | double precision | | | c5 | text | | | c6 | text | | | c7 | text | | | c8 | text | | |
Тогда порядок добавления столбцов должен точно соответствовать порядку столбцов в таблице базы данных. В данном примере он следующий:
tuple1.addColumn("ts", "2022-05-18 16:30:06");
tuple1.addColumn("tag", 102020030);
tuple1.addColumn("c1", 1.1);
tuple1.addColumn("c2", 2.2);
tuple1.addColumn("c3", 3.3);
tuple1.addColumn("c4", 4.4);
tuple1.addColumn("c5", "中文字符测试-1");
tuple1.addColumn("c6", "lTxFCVLwcDTKbNbjau_c6");
tuple1.addColumn("c7", "lTxFCVLwcDTKbNbjau_c7");
tuple1.addColumn("c8", "lTxFCVLwcDTKbNbjau_c8");
tuple2.addColumn("ts", "2022-05-18 16:30:06");
tuple2.addColumn("tag", 102020030);
tuple2.addColumn("c1", 1.1);
tuple2.addColumn("c2", 2.2);
tuple2.addColumn("c3", 3.3);
tuple2.addColumn("c4", 4.4);
tuple2.addColumn("c5", "中文字符测试-2");
tuple2.addColumn("c6", "lTxFCVLwcDTKbNbjau_c26");
tuple2.addColumn("c7", "lTxFCVLwcDTKbNbjau_c27");
tuple2.addColumn("c8", "lTxFCVLwcDTKbNbjau_c28");
Наконец, добавьте заполненный Tuple в MxClient.
client.appendTuples(tuple1, tuple2);
> ***Примечание!***
MxClient предоставляет несколько API: можно добавить один Tuple, несколько Tuple или список Tuples. Например: `client.appendTuple();`, `client.appendTupleList();`; также можно вызвать метод flush() объекта MxClient для ручной отправки данных независимо от количества записанных Tuple, например: `client.flush();`.
- Синхронная отправка данных с помощью MxClient
Синхронная отправка означает синхронную передачу Tuple в mxgate, что упрощает последующую обработку (например, фиксацию смещения Kafka).
Tuple tuple1 = client.generateEmptyTuple(); tuple1.addColumn("ts", "2022-05-18 16:30:06"); tuple1.addColumn("tag", 102020030); tuple1.addColumn("c1", 1.1); tuple1.addColumn("c2", 2.2); tuple1.addColumn("c3", 3.3); tuple1.addColumn("c4", 4.4); tuple1.addColumn("c5", "lTxFCVLwcDTKbNbjau_c5"); tuple1.addColumn("c6", "lTxFCVLwcDTKbNbjau_c6"); tuple1.addColumn("c7", "lTxFCVLwcDTKbNbjau_c7"); tuple1.addColumn("c8", "lTxFCVLwcDTKbNbjau_c8");
/*
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MxgateExample {
public static void main(String[] args) throws Exception {
MxgateExample http = new MxgateExample();
http.sendingPostRequest();
}
/*
* HTTP Post request
*/
private void sendingPostRequest() throws Exception {
/*
* mxgate listens on port 8086 of localhost
*/
String url = "http://localhost:8086/";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
/*
* Setting basic post request
*/
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type","text/plain");
String postJsonData = "public.testtable\n1603777821|1|101|201|301\n1603777822|2|102|202|302\n1603777823|3|103|203|303";
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
/*
* When the data is in Chinese, it can be encoded by postJsonData.getBytes("UTF-8")
*/
wr.write(postJsonData.toString().getBytes("UTF-8"));
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("Sending 'POST' request to URL : " + url);
System.out.println("Post Data : " + postJsonData);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String output;
StringBuffer response = new StringBuffer();
while ((output = in.readLine()) != null) {
response.append(output);
}
in.close();
System.out.println(response.toString());
}
}
import http.client
class MxgateExample(object):
def __init__(self):
/*
* mxgate listens on port 8086 of localhost
*/
self.url = "localhost:8086"
self.postData = "public.testtable\n/" \
"1603777821|1|101|201|301\n/" \
"1603777822|2|102|202|302\n/" \
"1603777823|3|103|203|303"
self.headers = {"Content-Type": "text/plain"}
/*
* HTTP Post request
*/
def sending_post_request(self):
conn = http.client.HTTPConnection(self.url)
conn.request("POST", "/", self.postData, self.headers)
response = conn.getresponse()
response_code = response.getcode()
print(f"Sending 'POST' request to URL : {self.url}")
print(f"Post Data : {self.postData}")
print(f"Response Code : {response_code}")
output = response.read()
print(output)
if __name__ == '__main__':
gate_post = MxgateExample()
gate_post.sending_post_request()
Рекомендуется использовать среду разработки C# Core
using System; using System.IO; using System.Net; using System.Text;
namespace HttpPostTest { class Program { static void Main(string[] args) { var url = "http://10.13.2.177:8086/"; var txt = "public.dest\n2021-01-01 00:00:00,1,a1\n2021-01-01 00:00:00,2,a2\n2021-01-01 00:00:00,3,a3";
HttpPost(url,txt);
}
public static string HttpPost(string url, string content){ string result = ""; HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.Method = "POST"; req.ContentType = "text/plain";
/*
* region Add Post parameters
*/
byte[] data = Encoding.UTF8.GetBytes(content);
req.ContentLength = data.Length;
using (Stream reqStream = req.GetRequestStream()){
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
/*
* Get the response content
*/
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)){
result = reader.ReadToEnd();
}
return result;
}
} }
> Если при подключении возникает ошибка ***** body size exceeds the given limit, необходимо увеличить значение `max-body-bytes` в разделе `mxgate.conf`.
### 3.4 Пример использования HTTP API MatrixGate на Golang
package main
import ( "bytes" "net/http" )
func PostDataToServer(URL string) error {
data := public.testtable 1603777821|1|101|201|301 1603777822|2|102|202|302 1603777823|3|103|203|303
resp, err := http.Post(URL, "application/text", bytes.NewBuffer([]byte(data)))
if err != nil {
return err
}
if resp.StatusCode != 200 {
/*
/*
* Обработка тела ответа.
*/
return nil
}
func main() { err := PostDataToServer("http://127.0.0.1:8086") if err != nil{ panic(err) }
}
>***Примечание!***
Дополнительную информацию о возможностях MatrixGate см. в [Руководстве по инструментам — mxgate](/ru/doc/5.1/tools/mxgate/feature).