diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index 6970f9968..b965f4a1f 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -589,6 +589,42 @@ filters=counter | QLA The requests pass through the filters from left to right in the order defined in the configuration parameter. +#### `monitor` + +The monitor parameter tells the service which cluster of servers to use. The +value of the option is the name of a monitor object. This removes the redundant +definition of servers in both services and monitors. + +If both the `monitor` and `servers` parameters are defined, only the `monitor` +parameter will be used. + +Only one cluster can be defined for a service. Multi-cluster setups should use +the `servers` parameter to list the servers that the service should use. + +Here is an excerpt from an example configuration with a service that defines the +cluster parameter. + +``` +[db-cluster-1-monitor] +type=monitor +module=mysqlmon +servers=server1,server2,server3 +user=maxuser +passwd=maxpwd +monitor_interval=1000 + +[my-readwrite-service] +type=service +router=readwritesplit +monitor=db-cluster-1-monitor +user=maxuser +passwd=maxpwd +``` + +The _db-cluster-1-monitor_ cluster consists of three servers monitored by a +_mysqlmon_ monitor module. The _my-readwrite-service_ uses this monitor as the +source for servers. + #### `servers` The servers parameter in a service definition provides a comma separated list of diff --git a/Documentation/Release-Notes/MaxScale-2.1.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.1.0-Release-Notes.md index 2676e7b1e..c6c621312 100644 --- a/Documentation/Release-Notes/MaxScale-2.1.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.1.0-Release-Notes.md @@ -158,6 +158,15 @@ following new commands were added to maxadmin, see output of `maxadmin help With these new features, you can start MaxScale without the servers and define them later. +### Monitors as server sources for services + +Services now accept a `monitor` parameter which can be used to point a service +to a cluster of servers that are monitored by a monitor. The value of the +`monitor` parameter should be the name of a monitor in the configuration name. + +For more details, refer to the [Configuration +Guide](../Getting-Started/Configuration-Guide.md#cluster) section on clusters. + ### Module commands Introduced in MaxScale 2.1, the module commands are special, module-specific diff --git a/server/core/config.c b/server/core/config.c index 279200ccb..9c44e9e25 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -119,6 +119,7 @@ static const char *service_params[] = "router", "router_options", "servers", + "monitor", "user", "passwd", // DEPRECATE: See config_get_password. "password", @@ -2800,16 +2801,45 @@ int configure_new_service(CONFIG_CONTEXT *context, CONFIG_CONTEXT *obj) int error_count = 0; char *filters = config_get_value(obj->parameters, "filters"); char *servers = config_get_value(obj->parameters, "servers"); + char *monitor = config_get_value(obj->parameters, "monitor"); char *roptions = config_get_value(obj->parameters, "router_options"); - char *router = config_get_value(obj->parameters, "router"); SERVICE *service = obj->element; if (service) { + if (monitor) + { + if (servers) + { + MXS_WARNING("Both `monitor` and `servers` are defined. Only the " + "value of `monitor` will be used."); + } + + /** `monitor` takes priority over `servers` */ + servers = NULL; + + for (CONFIG_CONTEXT *ctx = context; ctx; ctx = ctx->next) + { + if (strcmp(ctx->object, monitor) == 0) + { + servers = config_get_value(ctx->parameters, "servers"); + break; + } + } + + if (servers == NULL) + { + MXS_ERROR("Unable to find monitor '%s'.", monitor); + error_count++; + } + } + if (servers) { + char srv_list[strlen(servers) + 1]; + strcpy(srv_list, servers); char *lasts; - char *s = strtok_r(servers, ",", &lasts); + char *s = strtok_r(srv_list, ",", &lasts); while (s) { CONFIG_CONTEXT *obj1 = context; @@ -2820,6 +2850,7 @@ int configure_new_service(CONFIG_CONTEXT *context, CONFIG_CONTEXT *obj) { found = 1; serviceAddBackend(service, obj1->element); + break; } obj1 = obj1->next; }