MXS-2314 Add 'cluster' parameter to service

Using the cluster parameter, the servers of a service can be
defined using a monitor.

This change basically only introduces the parameter.
This commit is contained in:
Johan Wikman 2019-02-06 13:43:29 +02:00
parent 1073bc1832
commit f271c5cea1
6 changed files with 103 additions and 13 deletions

View File

@ -5,6 +5,7 @@
* Names starting with `@@` are reserved for use by MaxScale.
* Names can no longer contain whitespace.
* Servers can now be drained.
* The servers of a service can now be defined using a monitor.
For more details, please refer to:

View File

@ -1030,6 +1030,20 @@ in the name section of a block with a type parameter of server (see below).
servers=server1,server2,server3
```
*NOTE* The `servers` parameter is mutually exclusive with the `cluster` parameter.
#### `cluster`
The servers the service uses are defined by the monitor specified as value
of this configuration parameter.
```
cluster=TheMonitor
```
*NOTE* The `clusters` parameter is mutually exclusive with the `servers` parameter.
#### `user`
The user parameter, along with the password parameter are used to define the

View File

@ -63,6 +63,19 @@ being drained is the master, then it will not be possible to connect
unless `master_failure_mode` has been set to something else but the
default `fail_instantly`.
### Cluster
The servers a service uses can now be specified using the `cluster`
parameter of the service.
```
[TheService]
...
cluster=TheMonitor
```
In this case, the servers of the service will be defined by the
referred to monitor. Note that the parameters `servers` and `cluster`
are mutually exclusive.
## Bug fixes
[Here is a list of bugs fixed in MaxScale 2.4.0.](https://jira.mariadb.org/issues/?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20status%20%3D%20Closed%20AND%20fixVersion%20%3D%202.4.0)

View File

@ -93,6 +93,7 @@ const char CN_AUTH_WRITE_TIMEOUT[] = "auth_write_timeout";
const char CN_AUTO[] = "auto";
const char CN_CACHE_SIZE[] = "cache_size";
const char CN_CLASSIFY[] = "classify";
const char CN_CLUSTER[] = "cluster";
const char CN_CONNECTION_TIMEOUT[] = "connection_timeout";
const char CN_DATA[] = "data";
const char CN_DEFAULT[] = "default";
@ -314,6 +315,7 @@ const MXS_MODULE_PARAM config_service_params[] =
{CN_RETRY_ON_FAILURE, MXS_MODULE_PARAM_BOOL, "true"},
{CN_SESSION_TRACK_TRX_STATE, MXS_MODULE_PARAM_BOOL, "false"},
{CN_RETAIN_LAST_STATEMENTS, MXS_MODULE_PARAM_COUNT, "0"},
{CN_CLUSTER, MXS_MODULE_PARAM_STRING},
{NULL}
};
@ -1402,6 +1404,11 @@ std::unordered_set<CONFIG_CONTEXT*> get_dependencies(const std::vector<CONFIG_CO
}
}
if (type == CN_SERVICE && config_get_value(obj->parameters, CN_CLUSTER))
{
rval.insert(name_to_object(objects, obj, config_get_string(obj->parameters, CN_CLUSTER)));
}
if ((type == CN_MONITOR || type == CN_SERVICE) && config_get_value(obj->parameters, CN_SERVERS))
{
for (std::string name : mxs::strtok(obj->parameters->get_string(CN_SERVERS), ","))
@ -3679,6 +3686,16 @@ int create_new_service(CONFIG_CONTEXT* obj)
auto router = obj->parameters->get_string(CN_ROUTER);
mxb_assert(!router.empty());
const string servers = obj->parameters->get_string(CN_SERVERS);
const string cluster = obj->parameters->get_string(CN_CLUSTER);
if (!servers.empty() && !cluster.empty())
{
MXS_ERROR("Service '%s' is configured with both 'servers' and 'cluster'. "
"Only one or the other is allowed.", obj->object);
return 1;
}
char* user = config_get_value(obj->parameters, CN_USER);
char* auth = config_get_value(obj->parameters, CN_PASSWORD);
const MXS_MODULE* module = get_module(router.c_str(), MODULE_ROUTER);
@ -3704,21 +3721,24 @@ int create_new_service(CONFIG_CONTEXT* obj)
{
int error_count = 0;
for (auto& a : mxs::strtok(obj->parameters->get_string(CN_SERVERS), ","))
if (!servers.empty())
{
fix_object_name(a);
for (auto& a : mxs::strtok(servers, ","))
{
fix_object_name(a);
if (auto s = Server::find_by_unique_name(a))
{
serviceAddBackend(service, s);
}
else
{
MXS_ERROR("Unable to find server '%s' that is configured as part "
"of service '%s'.",
a.c_str(),
obj->object);
error_count++;
if (auto s = Server::find_by_unique_name(a))
{
serviceAddBackend(service, s);
}
else
{
MXS_ERROR("Unable to find server '%s' that is configured as part "
"of service '%s'.",
a.c_str(),
obj->object);
error_count++;
}
}
}
@ -3731,6 +3751,22 @@ int create_new_service(CONFIG_CONTEXT* obj)
error_count++;
}
}
if (!cluster.empty())
{
Monitor* pMonitor = monitor_find(cluster.c_str());
if (pMonitor)
{
service->m_monitor = pMonitor;
}
else
{
MXS_ERROR("Unable to find monitor '%s' that defines the cluster used by "
"service '%s'.", cluster.c_str(), obj->object);
error_count++;
}
}
}
else
{

View File

@ -21,6 +21,8 @@
#include "filter.hh"
class Monitor;
/**
* @file service.h - MaxScale internal service functions
*/
@ -103,6 +105,9 @@ public:
// TODO: Make these private
mutable std::mutex lock;
// TODO: Make this private.
Monitor* m_monitor { nullptr }; /**< A possibly associated monitor */
private:
FilterList m_filters; /**< Ordered list of filters */
std::string m_name; /**< Name of the service */
@ -399,5 +404,13 @@ json_t* service_relations_to_server(const SERVER* server, const char* host);
*/
json_t* service_relations_to_filter(const SFilterDef& filter, const char* host);
/**
* @brief Add server to all services associated with a monitor
*
* @param monitor A monitor.
* @param server A server.
*/
void service_add_server(Monitor* pMonitor, SERVER* pServer);
std::unique_ptr<ResultSet> serviceGetList(void);
std::unique_ptr<ResultSet> serviceGetListenerList(void);

View File

@ -148,6 +148,19 @@ static std::string get_version_string(MXS_CONFIG_PARAMETER* params)
return version_string;
}
void service_add_server(Monitor* pMonitor, SERVER* pServer)
{
LockGuard guard(this_unit.lock);
for (Service* pService : this_unit.services)
{
if (pService->m_monitor == pMonitor)
{
serviceAddBackend(pService, pServer);
}
}
}
Service::Service(const std::string& service_name,
const std::string& router_name,
MXS_CONFIG_PARAMETER* params)