github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/engine/pkg/promutil/test/multiprojects_metric_scences.go (about)

     1  // Copyright 2022 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package main
    15  
    16  import (
    17  	"net/http"
    18  	"sync"
    19  	"time"
    20  
    21  	"github.com/pingcap/log"
    22  	engineModel "github.com/pingcap/tiflow/engine/model"
    23  	"github.com/pingcap/tiflow/engine/pkg/promutil"
    24  	"github.com/pingcap/tiflow/engine/pkg/tenant"
    25  	"github.com/prometheus/client_golang/prometheus"
    26  )
    27  
    28  func main() {
    29  	var wg sync.WaitGroup
    30  	wg.Add(2)
    31  
    32  	go func() {
    33  		defer wg.Done()
    34  		log.Info("Start http listen on :8083")
    35  		err := http.ListenAndServe(":8083", nil) //nolint:gosec
    36  		if err != nil {
    37  			return
    38  		}
    39  	}()
    40  
    41  	go func() {
    42  		defer wg.Done()
    43  		log.Info("Start scenarios simulator")
    44  		simulator(&wg)
    45  	}()
    46  
    47  	wg.Wait()
    48  	log.Info("Exit scenarios metric test")
    49  }
    50  
    51  // simulator will simulate the usage of multi-projects/tasks prometheus metric,
    52  // Includes following scenarios:
    53  
    54  /// intra-framework test, SHOULD NOT have same metric name
    55  /// using different service name in K8s to distinguish metric
    56  // 1. one servermaster and one executor
    57  // 2. one servermaster and multi-executors
    58  
    59  /// intra-app metric test, SHOULD NOT have same metric
    60  // 3. one jobmaster and one worker of same job type in one executor
    61  
    62  /// multi-tasks metric isolation
    63  // 4. multi-jobmasters and multi-workers of same job type in one executor
    64  
    65  /// cross app metric isolation
    66  // 5. multi-jobmasters and multi-workers of different job type in one executor
    67  
    68  /// app and framework metric isolation
    69  // 6. one jobmaster in one executor, has same original metric name
    70  
    71  /// tenant/project metric isolation
    72  // 7. multi-jobmasters of same job type for different project
    73  
    74  func simulator(wg *sync.WaitGroup) {
    75  	scenes := []func(wg *sync.WaitGroup){
    76  		scenarios1OneServerOneExecutor, scenarios2OneServerMultiExecutor,
    77  		scenarios3OneJobmasterOneWorker, scenarios4OneJobmasterMultiWorker,
    78  		scenarios5MultiJobmasterMultiWorker, scenarios6OneJobmasterOneExecutor,
    79  		scenarios7MultiJobmasterMultiProjects,
    80  	}
    81  
    82  	for _, scene := range scenes {
    83  		scene(wg)
    84  	}
    85  }
    86  
    87  func scenarios1OneServerOneExecutor(wg *sync.WaitGroup) {
    88  	log.Info("Start scenarios1OneServerOneExecutor simulation...")
    89  	wg.Add(2)
    90  	go func() {
    91  		defer wg.Done()
    92  		// log.Info("Start scenarios1OneServerOneExecutor servermaster")
    93  		// we create new registry here to simulate running an isolation process or container
    94  		reg := promutil.NewRegistry()
    95  		http.Handle("/metric1", promutil.HTTPHandlerForMetricImpl(reg))
    96  
    97  		// one server
    98  		factory := promutil.NewFactory4FrameworkImpl(reg)
    99  		counter := factory.NewCounter(prometheus.CounterOpts{
   100  			Namespace: "dfe",
   101  			Subsystem: "servermaster",
   102  			Name:      "counter",
   103  
   104  			ConstLabels: prometheus.Labels{
   105  				"service": "svr1",
   106  			},
   107  		})
   108  		counter.Add(1)
   109  
   110  		for {
   111  			counter.Add(0.1)
   112  			time.Sleep(time.Second)
   113  		}
   114  	}()
   115  
   116  	go func() {
   117  		defer wg.Done()
   118  		// log.Info("Start scenarios1OneServerOneExecutor executor")
   119  		// we create new registry here to simulate running an isolation process or container
   120  		reg := promutil.NewRegistry()
   121  		http.Handle("/metric2", promutil.HTTPHandlerForMetricImpl(reg))
   122  
   123  		// one server
   124  		factory := promutil.NewFactory4FrameworkImpl(reg)
   125  		counter := factory.NewCounter(prometheus.CounterOpts{
   126  			Namespace: "dfe",
   127  			Subsystem: "executor",
   128  			Name:      "counter",
   129  
   130  			ConstLabels: prometheus.Labels{
   131  				"service": "svr2",
   132  			},
   133  		})
   134  		counter.Add(2)
   135  
   136  		for {
   137  			counter.Add(0.1)
   138  			time.Sleep(time.Second)
   139  		}
   140  	}()
   141  }
   142  
   143  func scenarios2OneServerMultiExecutor(wg *sync.WaitGroup) {
   144  	log.Info("Start scenarios2OneServerMultiExecutor simulation...")
   145  	wg.Add(2)
   146  	// We already create a servermaster in scenarios1OneServerOneExecutor, so we don't create one here
   147  	go func() {
   148  		defer wg.Done()
   149  		// log.Info("Start scenarios2OneServerMultiExecutor executor0")
   150  		// we create new registry here to simulate running an isolation process or container
   151  		reg := promutil.NewRegistry()
   152  		http.Handle("/metric3", promutil.HTTPHandlerForMetricImpl(reg))
   153  
   154  		// one server
   155  		factory := promutil.NewFactory4FrameworkImpl(reg)
   156  		counter := factory.NewCounter(prometheus.CounterOpts{
   157  			Namespace: "dfe",
   158  			Subsystem: "executor",
   159  			Name:      "counter",
   160  
   161  			ConstLabels: prometheus.Labels{
   162  				"service": "svr3",
   163  			},
   164  		})
   165  		counter.Add(3)
   166  
   167  		for {
   168  			counter.Add(0.1)
   169  			time.Sleep(time.Second)
   170  		}
   171  	}()
   172  
   173  	go func() {
   174  		defer wg.Done()
   175  		// log.Info("Start scenarios2OneServerMultiExecutor executor1")
   176  		// we create new registry here to simulate running an isolation process or container
   177  		reg := promutil.NewRegistry()
   178  		http.Handle("/metric4", promutil.HTTPHandlerForMetricImpl(reg))
   179  
   180  		// one server
   181  		factory := promutil.NewFactory4FrameworkImpl(reg)
   182  		counter := factory.NewCounter(prometheus.CounterOpts{
   183  			Namespace: "dfe",
   184  			Subsystem: "executor",
   185  			Name:      "counter",
   186  
   187  			ConstLabels: prometheus.Labels{
   188  				"service": "svr4",
   189  			},
   190  		})
   191  		counter.Add(4)
   192  
   193  		for {
   194  			counter.Add(0.1)
   195  			time.Sleep(time.Second)
   196  		}
   197  	}()
   198  }
   199  
   200  func scenarios3OneJobmasterOneWorker(wg *sync.WaitGroup) {
   201  	log.Info("Start scenarios3OneJobmasterOneWorker simulation...")
   202  	wg.Add(1)
   203  
   204  	tenant := tenant.NewProjectInfo(
   205  		"user0",
   206  		"proj0",
   207  	)
   208  	jobType := engineModel.JobTypeDM
   209  	jobID := "job0"
   210  	workerID := "worker0"
   211  
   212  	go func() {
   213  		defer wg.Done()
   214  		// log.Info("Start scenarios3OneJobmasterOneWorker jobmaster")
   215  		// we create new registry here to simulate running an isolation process or container
   216  		reg := promutil.NewRegistry()
   217  		http.Handle("/metric5", promutil.HTTPHandlerForMetricImpl(reg))
   218  
   219  		// one jobmaster
   220  		factory := promutil.NewFactory4MasterImpl(reg, tenant, jobType.String(), jobID)
   221  		counter0 := factory.NewCounter(prometheus.CounterOpts{
   222  			Namespace: "dm",
   223  			Subsystem: "jobmaster",
   224  			Name:      "counter",
   225  
   226  			ConstLabels: prometheus.Labels{
   227  				"service": "svr5",
   228  			},
   229  		})
   230  		counter0.Add(5)
   231  
   232  		// one worker
   233  		// log.Info("Start scenarios3OneJobmasterOneWorker worker0")
   234  		factory = promutil.NewFactory4WorkerImpl(reg, tenant, jobType.String(), jobID, workerID)
   235  		counter1 := factory.NewCounter(prometheus.CounterOpts{
   236  			Namespace: "dm",
   237  			Subsystem: "worker",
   238  			Name:      "counter",
   239  
   240  			ConstLabels: prometheus.Labels{
   241  				"service": "svr5",
   242  			},
   243  		})
   244  		counter1.Add(5)
   245  
   246  		counterVec := factory.NewCounterVec(prometheus.CounterOpts{
   247  			Namespace: "dm",
   248  			Subsystem: "worker",
   249  			Name:      "counter2",
   250  
   251  			ConstLabels: prometheus.Labels{
   252  				"service": "svr5",
   253  			},
   254  		},
   255  			[]string{"k1", "k2", "k3"},
   256  		)
   257  		curryCV, err := counterVec.CurryWith(prometheus.Labels{
   258  			"k3": "v3",
   259  		})
   260  		if err != nil {
   261  			log.Panic("curry with fail")
   262  		}
   263  		counter2, err := curryCV.GetMetricWithLabelValues([]string{"v1", "v2"}...)
   264  		if err != nil {
   265  			log.Panic("GetMetricWithLabelValues")
   266  		}
   267  		counter2.Add(5)
   268  
   269  		for {
   270  			counter0.Add(0.1)
   271  			counter1.Add(0.1)
   272  			counter2.Add(0.1)
   273  			time.Sleep(time.Second)
   274  		}
   275  	}()
   276  }
   277  
   278  func scenarios4OneJobmasterMultiWorker(wg *sync.WaitGroup) {
   279  	log.Info("Start scenarios4OneJobmasterMultiWorker simulation...")
   280  	wg.Add(1)
   281  
   282  	tenant := tenant.NewProjectInfo(
   283  		"user0",
   284  		"proj0",
   285  	)
   286  	jobType := engineModel.JobTypeDM
   287  	jobID := "job0"
   288  
   289  	go func() {
   290  		defer wg.Done()
   291  		// log.Info("Start scenarios4OneJobmasterMultiWorker jobmaster")
   292  		// we create new registry here to simulate running an isolation process or container
   293  		reg := promutil.NewRegistry()
   294  		http.Handle("/metric6", promutil.HTTPHandlerForMetricImpl(reg))
   295  
   296  		// one jobmaster
   297  		factory := promutil.NewFactory4MasterImpl(reg, tenant, jobType.String(), jobID)
   298  		counter0 := factory.NewCounter(prometheus.CounterOpts{
   299  			Namespace: "dm",
   300  			Subsystem: "jobmaster",
   301  			Name:      "counter",
   302  
   303  			ConstLabels: prometheus.Labels{
   304  				"service": "svr6",
   305  			},
   306  		})
   307  		counter0.Add(6)
   308  
   309  		// worker0
   310  		// log.Info("Start scenarios4OneJobmasterMultiWorker worker0")
   311  		factory = promutil.NewFactory4WorkerImpl(reg, tenant, jobType.String(), jobID, "worker0")
   312  		counter1 := factory.NewCounter(prometheus.CounterOpts{
   313  			Namespace: "dm",
   314  			Subsystem: "worker",
   315  			Name:      "counter",
   316  
   317  			ConstLabels: prometheus.Labels{
   318  				"service": "svr6",
   319  			},
   320  		})
   321  		counter1.Add(6)
   322  
   323  		// worker1
   324  		// log.Info("Start scenarios4OneJobmasterMultiWorker worker1")
   325  		factory = promutil.NewFactory4WorkerImpl(reg, tenant, jobType.String(), jobID, "worker1")
   326  		counter2 := factory.NewCounter(prometheus.CounterOpts{
   327  			Namespace: "dm",
   328  			Subsystem: "worker",
   329  			Name:      "counter",
   330  
   331  			ConstLabels: prometheus.Labels{
   332  				"service": "svr6",
   333  			},
   334  		})
   335  		counter2.Add(6)
   336  
   337  		for {
   338  			counter0.Add(0.1)
   339  			counter1.Add(0.1)
   340  			counter2.Add(0.1)
   341  			time.Sleep(time.Second)
   342  		}
   343  	}()
   344  }
   345  
   346  func scenarios5MultiJobmasterMultiWorker(wg *sync.WaitGroup) {
   347  	log.Info("Start scenarios5MultiJobmasterMultiWorker simulation...")
   348  	wg.Add(1)
   349  
   350  	tenant := tenant.NewProjectInfo(
   351  		"user0",
   352  		"proj0",
   353  	)
   354  	jobType0 := engineModel.JobTypeDM
   355  	jobType1 := engineModel.JobTypeCDC
   356  
   357  	jobID0 := "job0"
   358  	jobID1 := "job1"
   359  
   360  	workerID0 := "worker0"
   361  	workerID1 := "worker1"
   362  
   363  	go func() {
   364  		defer wg.Done()
   365  		// we create new registry here to simulate running an isolation process or container
   366  		reg := promutil.NewRegistry()
   367  		http.Handle("/metric7", promutil.HTTPHandlerForMetricImpl(reg))
   368  
   369  		// DM-jobmaster0
   370  		factory := promutil.NewFactory4MasterImpl(reg, tenant, jobType0.String(), jobID0)
   371  		counter0 := factory.NewCounter(prometheus.CounterOpts{
   372  			Subsystem: "jobmaster",
   373  			Name:      "counter",
   374  
   375  			ConstLabels: prometheus.Labels{
   376  				"service": "svr7",
   377  			},
   378  		})
   379  		counter0.Add(7)
   380  
   381  		// DM-jobmaster1
   382  		factory = promutil.NewFactory4MasterImpl(reg, tenant, jobType0.String(), jobID1)
   383  		counter1 := factory.NewCounter(prometheus.CounterOpts{
   384  			Subsystem: "jobmaster",
   385  			Name:      "counter",
   386  
   387  			ConstLabels: prometheus.Labels{
   388  				"service": "svr7",
   389  			},
   390  		})
   391  		counter1.Add(7)
   392  
   393  		// DM-worker0
   394  		factory = promutil.NewFactory4WorkerImpl(reg, tenant, jobType0.String(), jobID0, workerID0)
   395  		counter2 := factory.NewCounter(prometheus.CounterOpts{
   396  			Subsystem: "worker",
   397  			Name:      "counter",
   398  
   399  			ConstLabels: prometheus.Labels{
   400  				"service": "svr7",
   401  			},
   402  		})
   403  		counter2.Add(7)
   404  
   405  		// DM-worker1
   406  		factory = promutil.NewFactory4WorkerImpl(reg, tenant, jobType0.String(), jobID1, workerID1)
   407  		counter3 := factory.NewCounter(prometheus.CounterOpts{
   408  			Subsystem: "worker",
   409  			Name:      "counter",
   410  
   411  			ConstLabels: prometheus.Labels{
   412  				"service": "svr7",
   413  			},
   414  		})
   415  		counter3.Add(7)
   416  
   417  		// CDC-jobmaster0
   418  		factory = promutil.NewFactory4MasterImpl(reg, tenant, jobType1.String(), jobID0)
   419  		counter4 := factory.NewCounter(prometheus.CounterOpts{
   420  			Subsystem: "jobmaster",
   421  			Name:      "counter",
   422  
   423  			ConstLabels: prometheus.Labels{
   424  				"service": "svr7",
   425  				"type":    "cdc", // same original name but const labels are different
   426  			},
   427  		})
   428  		counter4.Add(7)
   429  
   430  		// CDC-jobmaster1
   431  		factory = promutil.NewFactory4MasterImpl(reg, tenant, jobType1.String(), jobID1)
   432  		counter5 := factory.NewCounter(prometheus.CounterOpts{
   433  			Subsystem: "jobmaster",
   434  			Name:      "counter",
   435  
   436  			ConstLabels: prometheus.Labels{
   437  				"service": "svr7",
   438  				"type":    "cdc", // same original name but const labels are different
   439  			},
   440  		})
   441  		counter5.Add(7)
   442  
   443  		// CDC-worker0
   444  		factory = promutil.NewFactory4WorkerImpl(reg, tenant, jobType1.String(), jobID0, workerID0)
   445  		counter6 := factory.NewCounter(prometheus.CounterOpts{
   446  			Subsystem: "worker",
   447  			Name:      "counter",
   448  
   449  			ConstLabels: prometheus.Labels{
   450  				"service": "svr7",
   451  				"type":    "cdc", // same original name but const labels are different
   452  			},
   453  		})
   454  		counter6.Add(7)
   455  
   456  		// CDC-worker1
   457  		factory = promutil.NewFactory4WorkerImpl(reg, tenant, jobType1.String(), jobID1, workerID1)
   458  		counter7 := factory.NewCounter(prometheus.CounterOpts{
   459  			Subsystem: "worker",
   460  			Name:      "counter",
   461  
   462  			ConstLabels: prometheus.Labels{
   463  				"service": "svr7",
   464  				"type":    "cdc", // same original name but const labels are different
   465  			},
   466  		})
   467  		counter7.Add(7)
   468  
   469  		for {
   470  			counter7.Add(0.1)
   471  			counter6.Add(0.1)
   472  			counter5.Add(0.1)
   473  			counter4.Add(0.1)
   474  			counter3.Add(0.1)
   475  			counter2.Add(0.1)
   476  			counter1.Add(0.1)
   477  			counter0.Add(0.1)
   478  			time.Sleep(time.Second)
   479  		}
   480  	}()
   481  }
   482  
   483  func scenarios6OneJobmasterOneExecutor(wg *sync.WaitGroup) {
   484  	log.Info("Start scenarios6OneJobmasterOneExecutor simulation...")
   485  	wg.Add(1)
   486  
   487  	tenant := tenant.NewProjectInfo(
   488  		"user0",
   489  		"proj0",
   490  	)
   491  	jobType := engineModel.JobTypeDM
   492  	jobID := "job0"
   493  
   494  	go func() {
   495  		defer wg.Done()
   496  		// we create new registry here to simulate running an isolation process or container
   497  		reg := promutil.NewRegistry()
   498  		http.Handle("/metric8", promutil.HTTPHandlerForMetricImpl(reg))
   499  
   500  		// one jobmaster
   501  		factory := promutil.NewFactory4MasterImpl(reg, tenant, jobType.String(), jobID)
   502  		counter0 := factory.NewCounter(prometheus.CounterOpts{
   503  			Name: "counter",
   504  
   505  			ConstLabels: prometheus.Labels{
   506  				"service": "svr8",
   507  			},
   508  		})
   509  		counter0.Add(8)
   510  
   511  		// one worker
   512  		factory = promutil.NewFactory4FrameworkImpl(reg)
   513  		counter1 := factory.NewCounter(prometheus.CounterOpts{
   514  			Name: "counter",
   515  
   516  			ConstLabels: prometheus.Labels{
   517  				"service": "svr8",
   518  			},
   519  		})
   520  		counter1.Add(8)
   521  
   522  		for {
   523  			counter0.Add(0.1)
   524  			counter1.Add(0.1)
   525  			time.Sleep(time.Second)
   526  		}
   527  	}()
   528  }
   529  
   530  func scenarios7MultiJobmasterMultiProjects(wg *sync.WaitGroup) {
   531  	log.Info("Start scenarios7MultiJobmasterMultiProjects simulation...")
   532  	wg.Add(1)
   533  
   534  	tenant0 := tenant.NewProjectInfo(
   535  		"user0",
   536  		"proj0",
   537  	)
   538  	tenant1 := tenant.NewProjectInfo(
   539  		"user1",
   540  		"proj1",
   541  	)
   542  	jobType := engineModel.JobTypeDM
   543  	jobID := "job0"
   544  
   545  	go func() {
   546  		defer wg.Done()
   547  		// we create new registry here to simulate running an isolation process or container
   548  		reg := promutil.NewRegistry()
   549  		http.Handle("/metric9", promutil.HTTPHandlerForMetricImpl(reg))
   550  
   551  		// project0
   552  		factory := promutil.NewFactory4MasterImpl(reg, tenant0, jobType.String(), jobID)
   553  		counter0 := factory.NewCounter(prometheus.CounterOpts{
   554  			Name: "counter",
   555  
   556  			ConstLabels: prometheus.Labels{
   557  				"service": "svr9",
   558  			},
   559  		})
   560  		counter0.Add(9)
   561  
   562  		// project1
   563  		factory = promutil.NewFactory4MasterImpl(reg, tenant1, jobType.String(), jobID)
   564  		counter1 := factory.NewCounter(prometheus.CounterOpts{
   565  			Name: "counter",
   566  
   567  			ConstLabels: prometheus.Labels{
   568  				"service": "svr9",
   569  			},
   570  		})
   571  		counter1.Add(9)
   572  
   573  		for {
   574  			counter0.Add(0.1)
   575  			counter1.Add(0.1)
   576  			time.Sleep(time.Second)
   577  		}
   578  	}()
   579  }