Partilhar via


Tutorial: Implementar um banco de dados distribuído geograficamente (Banco de Dados SQL do Azure)

Aplica-se a: do Banco de Dados SQL do Azure

Configure um banco de dados no Banco de Dados SQL e uma aplicação cliente para realizar o failover para uma região remota e teste um plano de failover. Você aprende a:

  • Criar um grupo de failover de
  • Executar um aplicativo Java para consultar um banco de dados no Banco de dados SQL
  • Failover de teste

Se você não tiver uma assinatura do Azure, crie uma conta gratuita antes de começar.

Pré-requisitos

Observação

Este artigo usa o módulo Azure Az PowerShell, que é o módulo PowerShell recomendado para interagir com o Azure. Para começar a usar o módulo Az PowerShell, consulte Instalar o Azure PowerShell. Para saber como migrar para o módulo Az PowerShell, consulte Migrar o Azure PowerShell do AzureRM para o Az.

Importante

O módulo PowerShell Azure Resource Manager (AzureRM) foi preterido em 29 de fevereiro de 2024. Todo o desenvolvimento futuro deve usar o módulo Az.Sql. Os usuários são aconselhados a migrar do AzureRM para o módulo Az PowerShell para garantir suporte e atualizações contínuos. O módulo AzureRM não é mais mantido ou suportado. Os argumentos para os comandos no módulo Az PowerShell e nos módulos AzureRM são substancialmente idênticos. Para obter mais informações sobre sua compatibilidade, consulte Apresentando o novo módulo do Az PowerShell.

Para concluir o tutorial, certifique-se de que instalou os seguintes itens:

Importante

Certifique-se de configurar regras de firewall para usar o endereço IP público do computador no qual você está executando as etapas neste tutorial. As regras de firewall no nível de banco de dados serão replicadas automaticamente para o servidor secundário.

Para obter informações, consulte Criar uma regra de firewall no nível de banco de dados ou para determinar o endereço IP usado para a regra de firewall no nível de servidor para seu computador, consulte Criar um firewall no nível de servidor.

Criar um grupo de failover

Usando o Azure PowerShell, crie grupos de failover entre um servidor existente e um novo servidor em outra região. Em seguida, adicione o banco de dados de exemplo ao grupo de failover.

Importante

Este exemplo requer o Azure PowerShell Az 1.0 ou posterior. Execute Get-Module -ListAvailable Az para ver quais versões estão instaladas. Se você precisar instalar, consulte Instalar o módulo do Azure PowerShell.

Execute Connect-AzAccount para entrar no Azure.

Para criar um grupo de failover, execute o seguinte script:

$admin = "<adminName>"
$password = "<password>"
$resourceGroup = "<resourceGroupName>"
$location = "<resourceGroupLocation>"
$server = "<serverName>"
$database = "<databaseName>"
$drLocation = "<disasterRecoveryLocation>"
$drServer = "<disasterRecoveryServerName>"
$failoverGroup = "<globallyUniqueFailoverGroupName>"

# create a backup server in the failover region
New-AzSqlServer -ResourceGroupName $resourceGroup -ServerName $drServer `
    -Location $drLocation -SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential `
    -ArgumentList $admin, $(ConvertTo-SecureString -String $password -AsPlainText -Force))

# create a failover group between the servers
New-AzSqlDatabaseFailoverGroup –ResourceGroupName $resourceGroup -ServerName $server `
    -PartnerServerName $drServer –FailoverGroupName $failoverGroup –FailoverPolicy Automatic -GracePeriodWithDataLossHours 2

# add the database to the failover group
Get-AzSqlDatabase -ResourceGroupName $resourceGroup -ServerName $server -DatabaseName $database | `
    Add-AzSqlDatabaseToFailoverGroup -ResourceGroupName $resourceGroup -ServerName $server -FailoverGroupName $failoverGroup

As configurações de replicação geográfica também podem ser alteradas no portal do Azure, selecionando seu banco de dados e, em seguida, Configurações>de Replicação Geográfica.

configurações de replicação geográfica

Executar o projeto de exemplo

  1. No console, crie um projeto Maven com o seguinte comando:

    mvn archetype:generate "-DgroupId=com.sqldbsamples" "-DartifactId=SqlDbSample" "-DarchetypeArtifactId=maven-archetype-quickstart" "-Dversion=1.0.0"
    
  2. Digite Y e pressione Enter.

  3. Altere os diretórios para o novo projeto.

    cd SqlDbSample
    
  4. Usando seu editor favorito, abra o arquivo pom.xml na pasta do projeto.

  5. Adicione o Microsoft JDBC Driver para dependência do SQL Server adicionando a seção dependency a seguir. A dependência deve ser colada dentro da seção dependencies maior.

    <dependency>
      <groupId>com.microsoft.sqlserver</groupId>
      <artifactId>mssql-jdbc</artifactId>
     <version>6.1.0.jre8</version>
    </dependency>
    
  6. Especifique a versão do Java adicionando a seção properties após a seção dependencies:

    <properties>
      <maven.compiler.source>1.8</maven.compiler.source>
      <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
  7. Dar suporte a ficheiros de manifesto ao adicionar a secção build após a secção properties.

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.0</version>
          <configuration>
            <archive>
              <manifest>
                <mainClass>com.sqldbsamples.App</mainClass>
              </manifest>
            </archive>
         </configuration>
        </plugin>
      </plugins>
    </build>
    
  8. Salve e feche o arquivo pom.xml.

  9. Abra o arquivo App.java localizado em .. \SqlDbSample\src\main\java\com\sqldbsamples e substitua o conteúdo pelo seguinte código:

    package com.sqldbsamples;
    
    import java.sql.Connection;
    import java.sql.Statement;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.Timestamp;
    import java.sql.DriverManager;
    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    
    public class App {
    
       private static final String FAILOVER_GROUP_NAME = "<your failover group name>";  // add failover group name
    
       private static final String DB_NAME = "<your database>";  // add database name
       private static final String USER = "<your admin>";  // add database user
       private static final String PASSWORD = "<password>";  // add database password
    
       private static final String READ_WRITE_URL = String.format("jdbc:" +
          "sqlserver://%s.database.windows.net:1433;database=%s;user=%s;password=%s;encrypt=true;" +
          "hostNameInCertificate=*.database.windows.net;loginTimeout=30;",
          FAILOVER_GROUP_NAME, DB_NAME, USER, PASSWORD);
       private static final String READ_ONLY_URL = String.format("jdbc:" +
          "sqlserver://%s.secondary.database.windows.net:1433;database=%s;user=%s;password=%s;encrypt=true;" +
          "hostNameInCertificate=*.database.windows.net;loginTimeout=30;",
          FAILOVER_GROUP_NAME, DB_NAME, USER, PASSWORD);
    
       public static void main(String[] args) {
          System.out.println("#######################################");
          System.out.println("## GEO DISTRIBUTED DATABASE TUTORIAL ##");
          System.out.println("#######################################");
          System.out.println("");
    
          int highWaterMark = getHighWaterMarkId();
    
          try {
             for(int i = 1; i < 1000; i++) {
                 //  loop will run for about 1 hour
                 System.out.print(i + ": insert on primary " +
                    (insertData((highWaterMark + i)) ? "successful" : "failed"));
                 TimeUnit.SECONDS.sleep(1);
                 System.out.print(", read from secondary " +
                    (selectData((highWaterMark + i)) ? "successful" : "failed") + "\n");
                 TimeUnit.SECONDS.sleep(3);
             }
          } catch(Exception e) {
             e.printStackTrace();
       }
    }
    
    private static boolean insertData(int id) {
       // Insert data into the product table with a unique product name so we can find the product again
       String sql = "INSERT INTO SalesLT.Product " +
          "(Name, ProductNumber, Color, StandardCost, ListPrice, SellStartDate) VALUES (?,?,?,?,?,?);";
    
       try (Connection connection = DriverManager.getConnection(READ_WRITE_URL);
               PreparedStatement pstmt = connection.prepareStatement(sql)) {
          pstmt.setString(1, "BrandNewProduct" + id);
          pstmt.setInt(2, 200989 + id + 10000);
          pstmt.setString(3, "Blue");
          pstmt.setDouble(4, 75.00);
          pstmt.setDouble(5, 89.99);
          pstmt.setTimestamp(6, new Timestamp(new Date().getTime()));
          return (1 == pstmt.executeUpdate());
       } catch (Exception e) {
          return false;
       }
    }
    
    private static boolean selectData(int id) {
       // Query the data previously inserted into the primary database from the geo replicated database
       String sql = "SELECT Name, Color, ListPrice FROM SalesLT.Product WHERE Name = ?";
    
       try (Connection connection = DriverManager.getConnection(READ_ONLY_URL);
               PreparedStatement pstmt = connection.prepareStatement(sql)) {
          pstmt.setString(1, "BrandNewProduct" + id);
          try (ResultSet resultSet = pstmt.executeQuery()) {
             return resultSet.next();
          }
       } catch (Exception e) {
          return false;
       }
    }
    
    private static int getHighWaterMarkId() {
       // Query the high water mark id stored in the table to be able to make unique inserts
       String sql = "SELECT MAX(ProductId) FROM SalesLT.Product";
       int result = 1;
       try (Connection connection = DriverManager.getConnection(READ_WRITE_URL);
               Statement stmt = connection.createStatement();
               ResultSet resultSet = stmt.executeQuery(sql)) {
          if (resultSet.next()) {
              result =  resultSet.getInt(1);
             }
          } catch (Exception e) {
           e.printStackTrace();
          }
          return result;
       }
    }
    
  10. Salve e feche o arquivo App.java.

  11. No console de comando, execute o seguinte comando:

    mvn package
    
  12. Inicie o aplicativo que será executado por cerca de 1 hora até ser interrompido manualmente, permitindo que você tenha tempo para executar o teste de failover.

    mvn -q -e exec:java "-Dexec.mainClass=com.sqldbsamples.App"
    
    #######################################
    ## GEO DISTRIBUTED DATABASE TUTORIAL ##
    #######################################
    
    1. insert on primary successful, read from secondary successful
    2. insert on primary successful, read from secondary successful
    3. insert on primary successful, read from secondary successful
    ...
    

Failover de teste

Execute os scripts a seguir para simular um failover e observar os resultados do aplicativo. Observe como algumas inserções e seleções falharão durante a migração do banco de dados.

Você pode verificar a função do servidor de recuperação de desastres durante o teste com o seguinte comando:

(Get-AzSqlDatabaseFailoverGroup -FailoverGroupName $failoverGroup `
    -ResourceGroupName $resourceGroup -ServerName $drServer).ReplicationRole

Para testar um failover:

  1. Inicie um failover manual do grupo de failover:

    Switch-AzSqlDatabaseFailoverGroup -ResourceGroupName $resourceGroup `
     -ServerName $drServer -FailoverGroupName $failoverGroup
    
  2. Reverta o grupo de failover de volta para o servidor primário:

    Switch-AzSqlDatabaseFailoverGroup -ResourceGroupName $resourceGroup `
     -ServerName $server -FailoverGroupName $failoverGroup
    

Próximos passos

Analise a lista de verificação de alta disponibilidade e recuperação de desastres .

Conteúdo relacionado do Banco de Dados SQL do Azure: